反序列化的XML与DataContractSerializer的
我有一个返回下列数据的Web服务:反序列化的XML与DataContractSerializer的
<?xml version=""1.0"" encoding=""UTF-8""?>
<RESPONSE>
<KEY>12345</KEY>
<PROPERTY>
<PROPERTY_ADDRESS>
<STREET_NUM>25</STREET_NUM>
<STREET_ADDRESS>ELM ST</STREET_ADDRESS>
<STREET_PREFIX/>
<STREET_NAME>ELM</STREET_NAME>
<STREET_TYPE>ST</STREET_TYPE>
<STREET_SUFFIX/>
</PROPERTY_ADDRESS>
</PROPERTY>
</RESPONSE>
我有一类结构相匹配:
[DataContract(Name="RESPONSE", Namespace="")]
public class Response
{
[DataMember(Name="KEY")]
public string Key { get; set; }
[DataMember(Name = "PROPERTY")]
public Property Property { get; set; }
}
[DataContract(Name="PROPERTY", Namespace="")]
public class Property
{
[DataMember(Name="PROPERTY_ADDRESS")]
public PropertyAddress Address { get; set; }
}
[DataContract(Name="PROPERTY_ADDRESS", Namespace="")]
public class PropertyAddress
{
[DataMember(Name="STREET_NUM")]
public string StreetNumber { get; set; }
[DataMember(Name = "STREET_ADDRESS")]
public string StreetAddress { get; set; }
[DataMember(Name = "STREET_PREFIX")]
public string StreetPrefix { get; set; }
[DataMember(Name = "STREET_NAME")]
public string StreetName { get; set; }
[DataMember(Name = "STREET_TYPE")]
public string StreetType { get; set; }
[DataMember(Name = "STREET_SUFFIX")]
public string StreetSuffix { get; set; }
}
我反序列化的代码如下所示:
[Test]
public void TestMapping()
{
var serializer = new DataContractSerializer(typeof(Response));
Response response = null;
using (var ms = new MemoryStream(Encoding.UTF8.GetBytes(XmlData)))
{
response = (Response)serializer.ReadObject(ms);
}
//This works
Assert.AreEqual("12345", response.Key);
//This works
Assert.AreEqual("25", response.Property.Address.StreetNumber);
//This FAILS. StreetAddress is null
Assert.AreEqual("ELM ST", response.Property.Address.StreetAddress);
}
对于我的生活,我无法弄清楚为什么StreetAddress失败。这很简单,我错过了。
DataContractSerializer希望事情是in alphabetical order。您需要将Order
添加到您的数据成员才能正常工作。
[DataContract(Name = "PROPERTY_ADDRESS", Namespace = "")]
public class PropertyAddress
{
[DataMember(Name = "STREET_NUM", Order=0)]
public string StreetNumber { get; set; }
[DataMember(Name = "STREET_ADDRESS", Order=1)]
public string StreetAddress { get; set; }
[DataMember(Name = "STREET_PREFIX", Order=2)]
public string StreetPrefix { get; set; }
[DataMember(Name = "STREET_NAME", Order=3)]
public string StreetName { get; set; }
[DataMember(Name = "STREET_TYPE", Order=4)]
public string StreetType { get; set; }
[DataMember(Name = "STREET_SUFFIX",Order=5)]
public string StreetSuffix { get; set; }
}
@Micah:它的性能原因。通过以特定顺序预期标签,DataContractSerializer可以节省将合同标签与消息标签进行匹配的时间。如果没有明确指定,则必须有一些默认的顺序。 – Vizu 2013-03-14 16:47:25
我认为任何'性能'收益都被浪费的开发人员在试图发现,调试和修复这个愚蠢的需求时所浪费的大量时间所抵消。 – 2013-07-01 08:29:12
所以...你如何禁用这种行为? – BrainSlugs83 2013-09-27 22:30:27
你必须增强与元素的顺序数据合同,因为DataContractSerializer的预期元素被默认字母顺序排序。你的XML不是这种情况。
下面的代码:
[DataContract(Name = "PROPERTY_ADDRESS", Namespace = "")]
public class PropertyAddress
{
[DataMember(Name = "STREET_NUM", Order=1)]
public string StreetNumber { get; set; }
[DataMember(Name = "STREET_ADDRESS", Order=2)]
public string StreetAddress { get; set; }
[DataMember(Name = "STREET_PREFIX", Order=3)]
public string StreetPrefix { get; set; }
[DataMember(Name = "STREET_NAME", Order=4)]
public string StreetName { get; set; }
[DataMember(Name = "STREET_TYPE", Order=5)]
public string StreetType { get; set; }
[DataMember(Name = "STREET_SUFFIX", Order=6)]
public string StreetSuffix { get; set; }
}
什么样的价值,你在那些财产,恰好,你可以做每财产testcontext.writeline看到价值。 – 2013-03-14 15:35:42
response.Property.Address.StreetNumber ==“25” response.Property.Address.StreetAddress == null – Micah 2013-03-14 15:36:24
将StreetAddress更改为int以查看它是否属性名称或类型失败。 – 2013-03-14 15:42:13