我在由XmlSerializer序列化的字符串中有一个序列化对象。我希望使用DataContractSerializer对其进行反序列化。
此代码生成一个空对象:
Dim Enc As New UTF8Encoding
Using Stream As New MemoryStream(Enc.GetBytes(rec.XML))
Dim xtr As New XmlTextReader(Stream)
Dim Formatter As New DataContractSerializer(GetType(SMTPSettings))
smtp = Formatter.ReadObject(xtr, False)
End Using
字符串如下:
<?xml version="1.0"?>
<SMTPSettings xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<Host>mail.clubcompete.com</Host>
<Port>26</Port>
<UserName>outgoing@clubcompete.com</UserName>
<Password>xxxxxxxxx</Password>
<UseSSL>false</UseSSL>
<TestEmailAddress>al@xxxxx-micro.com</TestEmailAddress>
</SMTPSettings>
如何使用DataContractSerializer反序列化字符串?我无法使用XmlSerializer,因为它会在我的服务器临时文件夹中创建DLL,并且Web主机不允许这样做。
1条答案
按热度按时间rqmkfv5c1#
你没有显示你的类
SMTPSettings
,所以我猜它看起来像这样:如果您希望使用
DataContractSerializer
将问题中显示的XML反序列化为此类,则需要记住与XmlSerializer
的以下区别:DataContractSerializer
不支持XML属性(除了命名空间属性和特殊属性,例如xsi:type
)。请参阅here以进行确认。幸运的是,XML不包含这样的属性。
DataContractSerializer
不支持序列化没有外部容器元素的集合。幸运的是,您的XML不包含没有外部容器的重复元素,因此这不适用。
1.默认命名空间的推断方式不同。
XmlSerializer
假定类型在空XML命名空间中序列化,除非应用了XmlRootAttribute.Namespace
之类的属性。DataContractSerializer
假定类型在默认情况下在非空XML命名空间中序列化,特别是http://schemas.datacontract.org/2004/07/Clr.Namespace
。有关确认信息,请参见数据协定命名空间。由于您的XML不在任何命名空间中,因此您需要将data contract attrtibutes套用至您的型别,以指定空的命名空间。
1.元素必须排序。
XmlSerializer
允许元素以任何顺序排列,但DataContractSerializer
要求元素以特定顺序排列。有关详细信息,请参见Data Member Order。如果未使用数据协定属性指定顺序,则数据协定序列化程序假定元素应按字母顺序进行序列化。由于XML元素不是按字母顺序排列的,因此需要再次使用数据协定属性来指定所需的顺序。
将所有这些放在一起,可以使用以下版本的
SMTPSettings
来反序列化该XML示例:演示小提琴#1(在c#中)here。
考虑到
DataContractSerializer
的所有限制,您可以考虑将类加载到LINQ to XMLXElement
中,然后手动填充SMTPSettings
,如下所示:这完全避免了对元素顺序的繁琐。
演示小提琴#2