如何用DataContractSerializer反序列化XmlSerializer序列化的对象?
使用DataContractSerializer反序列化XmlSerializer生成的XML字符串
问题描述
我有一个由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字符串内容如下:
<?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>
由于主机不允许在临时文件夹生成DLL,无法使用XmlSerializer,请问如何解决?
解决方案
1. 正确标记SMTPSettings类的DataContract属性
DataContractSerializer默认会使用特定命名空间,而XmlSerializer生成的XML无该命名空间,同时需要确保每个属性的DataMember名称与XML元素完全匹配。修改类定义如下:
<DataContract(Name:= "SMTPSettings", Namespace:= "")> Public Class SMTPSettings <DataMember(Name:= "Host")> Public Property Host As String <DataMember(Name:= "Port")> Public Property Port As Integer <DataMember(Name:= "UserName")> Public Property UserName As String <DataMember(Name:= "Password")> Public Property Password As String <DataMember(Name:= "UseSSL")> Public Property UseSSL As Boolean <DataMember(Name:= "TestEmailAddress")> Public Property TestEmailAddress As String End Class
DataContract的Namespace设为空,匹配原XML的无命名空间结构- 每个
DataMember显式指定Name,确保与XML中的元素名(大小写、拼写)完全一致
2. 优化反序列化代码(推荐)
XmlTextReader已过时,建议使用XmlReader.Create替代,代码逻辑保持不变:
Dim enc As New UTF8Encoding() Using stream As New MemoryStream(enc.GetBytes(rec.XML)) Using reader As XmlReader = XmlReader.Create(stream) Dim serializer As New DataContractSerializer(GetType(SMTPSettings)) smtp = DirectCast(serializer.ReadObject(reader), SMTPSettings) End Using End Using
原理说明
空对象的核心原因是DataContractSerializer与XmlSerializer的XML结构规则不兼容:
- DataContractSerializer默认会给类型和成员添加默认命名空间,原XML无该命名空间导致无法匹配
- 若不指定DataMember的Name,DataContractSerializer会按默认规则(如驼峰命名)匹配,与XmlSerializer生成的帕斯卡命名元素不匹配
内容的提问来源于stack exchange,提问作者DrMicrochip
相关产品推荐
相关产品推荐

