#c# #xml #xml-deserialization
#c# #xml #xml-десериализация
Вопрос:
XML, подлежащий десериализации:
<CheckOnlineStatus xmlns:i="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://schemas.datacontract.org/2004/07/Lifecare.LIS.Integration.Hyland.Models">
<Database>string</Database>
<InstancesStillNearline>0</InstancesStillNearline>
<SeriesLocationMap xmlns:d2p1="http://schemas.microsoft.com/2003/10/Serialization/Arrays">
<d2p1:KeyValueOfstringboolean>
<d2p1:Key>test</d2p1:Key>
<d2p1:Value>true</d2p1:Value>
</d2p1:KeyValueOfstringboolean>
<d2p1:KeyValueOfstringboolean>
<d2p1:Key>test1</d2p1:Key>
<d2p1:Value>false</d2p1:Value>
</d2p1:KeyValueOfstringboolean>
</SeriesLocationMap>
<Status>string</Status>
<StudyInstanceUID>string</StudyInstanceUID>
<TotalClips>0</TotalClips>
<TotalExecutionTime>0</TotalExecutionTime>
<TotalInstances>0</TotalInstances>
</CheckOnlineStatus>
Используемые модели данных:
using System.Collections.Generic;
using System.Xml.Serialization;
[XmlRoot("CheckOnlineStatus")]
/// <summary>
/// The CheckOnlineStatus entity.
/// </summary>
public class CheckOnlineStatus
{
[XmlElement("Status")]
/// <summary>
/// Gets or sets the Status
/// </summary>
public string Status { get; set; }
[XmlElement("Database")]
/// <summary>
/// Gets or sets the Database
/// </summary>
public string Database { get; set; }
/// <summary>
/// Gets or sets the StudyInstanceUID
/// </summary>
[XmlElement("StudyInstanceUID")]
public string StudyInstanceUID { get; set; }
/// <summary>
/// Gets or sets the TotalExecutionTime
/// </summary>
[XmlElement("TotalExecutionTime")]
public long TotalExecutionTime { get; set; }
/// <summary>
/// Gets or sets the TotalInstances
/// </summary>
[XmlElement("TotalInstances")]
public int TotalInstances { get; set; }
/// <summary>
/// Gets or sets the TotalClips
/// </summary>
[XmlElement("TotalClips")]
public int TotalClips { get; set; }
/// <summary>
/// Gets or sets the InstancesStillNearline
/// </summary>
[XmlElement("InstancesStillNearline")]
public int InstancesStillNearline { get; set; }
/// <summary>
/// Gets or sets the dictionary of series location map
/// </summary>
[XmlElement("SeriesLocationMap")]
public Dictionary<string, bool> SeriesLocationMap { get; set; }
}
Код десериализации, здесь результат выше xml в строковом формате:
(CheckOnlineStatus)new XmlSerializer(typeof(CheckOnlineStatus)).Deserialize(new MemoryStream(Encoding.UTF8.GetBytes(result)));
Я получаю ошибку ниже во время выполнения:
Не удается сериализовать файл Lifecare.LIS.Integration.NDP.Models участника.Проверьте linestatus.SeriesLocationMap системы типов.Коллекции.Generic.Dictionary`2[[System.Строка, mscorlib, Версия= 4.0.0.0, Культура = нейтральная, PublicKeyToken=b77a5c561934e089],[Система.Логическое значение, mscorlib, версия = 4.0.0.0, Культура = нейтральная, PublicKeyToken=b77a5c561934e089]], потому что он реализует IDictionary.
Я попробовал пару других вещей, но это не сработало, например. https://www.codeproject.com/Questions/716556/XML-deserialize-Attributes-to-dictionary
Может кто-нибудь, пожалуйста, помогите здесь. Спасибо.
Ответ №1:
Поскольку исключение ( InvalidOperationException
с внутренним UnsupportedException
) говорит, что вы не можете просто десериализовать его в a Dictionary
.
Вот один из способов преодолеть эту трудность:
Определение ключевого значения
[Serializable]
public struct KeyValue
{
public string Key { get; set; }
public bool Value { get; set; }
}
В качестве альтернативы вы можете воспользоваться встроенным KeyValuePair<TKey, TValue>
Использование XmlArray
и XmlArrayItem
[XmlArray("SeriesLocationMap")]
[XmlArrayItem("KeyValueOfstringboolean")]
public List<KeyValue> IntermediateContainer { get; set; }
Используется XmlIgnore
для преобразования списка в Dictionary<string, bool>
[XmlIgnore]
public Dictionary<string, bool> SeriesLocationMap => IntermediateContainer.ToDictionary(x => x.Key, y => y.Value);
Я тестировал его без пространств имен, поэтому вам нужно указать их в нужном месте, чтобы иметь возможность правильно их прочитать.
В качестве альтернативы вы можете попробовать использовать DataContractSerializer
тот, который поддерживает Dictionary.
Комментарии:
1. Спасибо. DataSerializer исправил проблему для нас