[英]DataContract serializer not deserializing into a list repeating XML elements without container element
We are facing a situation where the DataContract
serializer (a WCF service) is not deserializing repeating XML elements without container element into a list;我们面临的情况是
DataContract
序列化程序(WCF 服务)没有将没有容器元素的重复 XML 元素反序列化到列表中; the list property ends up with zero elements. list 属性以零元素结束。
The datacontracts we have:我们拥有的数据合约:
[DataContract]
public class Requestor
{
[DataMember(IsRequired = true, Order = 0)]
public string RequestorRole;
[DataMember(IsRequired = true, Order = 1)]
public string RequestorGivenName;
[DataMember(IsRequired = true, Order = 2)]
public string RequestorSurName;
[DataMember(IsRequired = false, Order = 3)]
public List<RequestorIdentification> RequestorIdentification { get; set; }
}
[DataContract]
public class RequestorIdentification
{
[DataMember(IsRequired = true, Order = 0)]
public string IdentificationID;
[DataMember(IsRequired = true, Order = 1)]
public string IdentificationCategoryCode;
}
The XML we want to deserialize:我们要反序列化的 XML:
<Requestor xmlns="http://schemas.datacontract.org/2004/07/Serialization"> <RequestorRole>Physicians</RequestorRole> <RequestorGivenName>Rich</RequestorGivenName> <RequestorSurName>Smith</RequestorSurName> <RequestorIdentification> <IdentificationID>AB1234567</IdentificationID> <IdentificationCategoryCode>DEA</IdentificationCategoryCode> </RequestorIdentification> <RequestorIdentification> <IdentificationID>0123456789</IdentificationID> <IdentificationCategoryCode>NPI</IdentificationCategoryCode> </RequestorIdentification> </Requestor>
How can we resolve the issue using the DataContract
serializer?我们如何使用
DataContract
序列化程序解决问题?
So far we have found no way to make it work, and this page https://docs.microsoft.com/en-us/dotnet/framework/wcf/feature-details/collection-types-in-data-contracts was not of much help.到目前为止,我们还没有找到让它工作的方法,而且这个页面https://docs.microsoft.com/en-us/dotnet/framework/wcf/feature-details/collection-types-in-data-contracts不是有很大帮助。
The same issue was resolved for the XmlSerializer
in this question:此问题中的
XmlSerializer
解决了相同的问题:
Deserializing into a List without a container element in XML在 XML 中反序列化为没有容器元素的 List
To deserialize the XML shown in the OP, one can use XmlElement .要反序列化 OP 中显示的 XML,可以使用XmlElement 。 However, this requires the use of XmlSerializer instead of DataContractSerializer for serialization and deserialization.
但是,这需要使用XmlSerializer而不是DataContractSerializer进行序列化和反序列化。
The DataContractSerializer does not support the programming model used by the XmlSerializer and ASP.NET Web services.
DataContractSerializer 不支持 XmlSerializer 和 ASP.NET Web 服务使用的编程模型。 In particular, it does not support attributes like XmlElementAttribute and XmlAttributeAttribute.
特别是,它不支持 XmlElementAttribute 和 XmlAttributeAttribute 等属性。 To enable support for this programming model, WCF must be switched to use the XmlSerializer instead of the DataContractSerializer.
若要启用对此编程模型的支持,必须将 WCF 切换为使用 XmlSerializer 而不是 DataContractSerializer。
The code below shows how one can deserialize the XML shown in the OP.下面的代码显示了如何反序列化 OP 中显示的 XML。
Create a Windows Forms App (.NET Framework)创建 Windows 窗体应用程序 (.NET Framework)
Add Reference (System.Runtime.Serialization)添加引用(System.Runtime.Serialization)
VS 2019 VS 2019
The following using directives are used in the code below :以下代码中使用了以下 using 指令:
using System;
using System.Collections.Generic;
using System.IO;
using System.Runtime.Serialization;
using System.Text;
using System.Xml;
using System.Xml.Serialization;
Create a class (name: RequestorRequestorIdentification.cs)创建一个类(名称:RequestorRequestorIdentification.cs)
[DataContract(Name = "RequestorIdentification")]
public class RequestorRequestorIdentification
{
[DataMember]
public string IdentificationID { get; set; }
[DataMember]
public string IdentificationCategoryCode { get; set; }
}
Create a class (name: Requestor.cs)创建一个类(名称:Requestor.cs)
[DataContract(Name ="Requestor")]
public class Requestor
{
[DataMember]
public string RequestorRole { get; set; }
[DataMember]
public string RequestorGivenName { get; set; }
[DataMember]
public string RequestorSurName { get; set; }
[XmlElement]
public List<RequestorRequestorIdentification> RequestorIdentification { get; set; } = new List<RequestorRequestorIdentification>();
}
Note : The use of XmlElement requires the use of XmlSerializer instead of DataContractSerializer for serialization and deserialization.注意:使用XmlElement需要使用XmlSerializer而不是DataContractSerializer进行序列化和反序列化。
Create a class (name: HelperXml.cs)创建一个类(名称:HelperXml.cs)
public class HelperXml
{
public static T DeserializeXMLFileToObject<T>(string xmlFilename)
{
//usage: Requestor requestor = DeserializeXMLFileToObject<Requestor>(xmlFilename);
if (String.IsNullOrEmpty(xmlFilename))
throw new Exception("Error: xmlFilename is null or empty.");
return DeserializeXMLToObject<T>(File.ReadAllBytes(xmlFilename));
}
public static T DeserializeXMLToObject<T>(string xmlText)
{
//usage: Requestor requestor = DeserializeXMLToObject<Requestor>(xmlText);
//create new instance
using (System.IO.StringReader reader = new System.IO.StringReader(xmlText))
{
System.Xml.Serialization.XmlSerializer serializer = new System.Xml.Serialization.XmlSerializer(typeof(T), "http://schemas.datacontract.org/2004/07/Serialization");
return (T)serializer.Deserialize(reader);
}
}
public static T DeserializeXMLToObject<T>(byte[] xmlBytes)
{
//usage: Requestor requestor = DeserializeXMLToObject<Requestor>(File.ReadAllBytes(xmlFilename));
//create new instance of MemoryStream
using (MemoryStream ms = new MemoryStream(xmlBytes))
{
using (XmlTextReader reader = new XmlTextReader(ms))
{
System.Xml.Serialization.XmlSerializer serializer = new System.Xml.Serialization.XmlSerializer(typeof(T), "http://schemas.datacontract.org/2004/07/Serialization");
return (T)serializer.Deserialize(reader);
}
}
}
public static void SerializeObjectToXMLFile(object obj, string xmlFilename)
{
//Usage: Class1 myClass1 = new Class1();
//SerializeObjectToXMLFile(myClass1, xmlFilename);
if (String.IsNullOrEmpty(xmlFilename))
throw new Exception("Error: xmlFilename is null or empty.");
//Xml writer settings
XmlWriterSettings settings = new XmlWriterSettings();
settings.OmitXmlDeclaration = true;
settings.Encoding = Encoding.UTF8;
settings.Indent = true;
using (XmlWriter writer = XmlWriter.Create(xmlFilename, settings))
{
//specify namespaces
System.Xml.Serialization.XmlSerializerNamespaces ns = new System.Xml.Serialization.XmlSerializerNamespaces();
ns.Add(string.Empty, "http://schemas.datacontract.org/2004/07/Serialization");
//create new instance
System.Xml.Serialization.XmlSerializer serializer = new System.Xml.Serialization.XmlSerializer(obj.GetType(), "http://schemas.datacontract.org/2004/07/Serialization");
//write to XML file
serializer.Serialize(writer, obj, ns);
}
}
}
Usage (deserialize):用法(反序列化):
private Requestor _requestor = null;
...
//deserialize
//_requestor = HelperXml.DeserializeXMLFileToObject<Requestor>(Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments), "Test.xml"));
//_requestor = HelperXml.DeserializeXMLToObject<Requestor>(System.Text.Encoding.UTF8.GetBytes(xmlText));
_requestor = HelperXml.DeserializeXMLToObject<Requestor>(xmlText);
Usage (serialize):用法(序列化):
private Requestor _requestor = null;
...
//create new instance
_requestor = new Requestor();
_requestor.RequestorRole = "Physicians";
_requestor.RequestorGivenName = "Rich";
-requestor.RequestorSurName = "Smith";
_requestor.RequestorIdentification.Add(new RequestorRequestorIdentification() { IdentificationID = "AB1234567", IdentificationCategoryCode = "DEA" });
_requestor.RequestorIdentification.Add(new RequestorRequestorIdentification() { IdentificationID = "0123456789", IdentificationCategoryCode = "NPI" });
using (SaveFileDialog sfd = new SaveFileDialog())
{
sfd.Filter = "XML File (*.xml)|*.xml";
sfd.FileName = "Test.xml";
if (sfd.ShowDialog() == DialogResult.OK)
{
HelperXml.SerializeObjectToXMLFile(_requestor, sfd.FileName);
Debug.WriteLine($"Info: Saved to '{sfd.FileName}'");
}
}
Additional Resources :其他资源:
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.