我无法从API调用反序列化XML响应。我的'Option'对象的属性'Description'为空。
以下是XML示例:
<vehicle found="1">
<description>VehicleDescText</description>
<buildDate>2000-11-20</buildDate>
<modelYear>2001</modelYear>
<optionList>
<option code="UH8">OptionDesc1</option>
<option code="UH8">OptionDesc2</option>
</optionList>
</vehicle>
以下是C#类的示例:
[DataContract]
[XmlRoot("vehicle")]
public class Vehicle
{
[DataMember]
[XmlAttribute("found")]
public bool Found { get; set; }
[DataMember]
[XmlElement("description")]
public string Description { get; set; }
[DataMember]
[XmlElement("buildDate")]
public string BuildDate { get; set; }
[DataMember]
[XmlElement("modelYear")]
public string ModelYear { get; set; }
[DataMember]
[XmlElement("optionList")]
public List<Option> OptionList { get; set; }
}
public class Option
{
[DataMember]
[XmlAttribute("code")]
public string Code { get; set; }
[DataMember]
[XmlElement("option")]
public string Description { get; set; }
}
反序列化对象如下所示:
var xmlDeserializer = new RestSharp.Deserializers.XmlDeserializer();
results = xmlDeserializer.Deserialize<Vehicle>(response);
我在哪里错了?由于我不想修改底层数据模型,我可以添加或修改哪些属性来解决问题?
答案 0 :(得分:6)
您已使用XML serializer attributes和data contract attributes标记了自己的类型,但您使用的反序列化程序RestSharp.Deserializers.XmlDeserializer
不支持这些属性。
相反,正如其documentation中所解释的,它支持[DeserializeAs]
属性,该属性允许控制XML节点名称和元素与属性状态。
但正如@apocalypse's answer以及this older question中所述,文档中有关于将元素值反序列化为属性值的特殊情况:
如果返回的XML是这样的:
<Response>Hello world</Response>
无法直接在C#类中表示:
public class Response { }
您需要一些东西来保存Response元素的值。在这 case,添加一个名为Value的属性,它将被填充:
public class Response { public string Value { get; set; } }
在搜索匹配元素之间检查此条件 名称和匹配的属性名称。
即。如果您将Description
重命名为Value
,则可以成功反序化该XML。 (Sample fiddle #1。)
但是,您似乎不希望重命名Description
媒体资源。如果是这样,您可以将[DeserializeAs(Name = "Value")]
应用于它,特殊情况将再次适用:
public class Option
{
public string Code { get; set; }
[DeserializeAs(Name = "Value")]
public string Description { get; set; }
}
示例fiddle #2。
最后,作为替代解决方案,您可以切换到RestSharp.Deserializers.DotNetXmlDeserializer
并使用常规XmlSerializer
属性,特别是[XmlText]
。因此,您的代码将成为:
var xmlDeserializer = new RestSharp.Deserializers.DotNetXmlDeserializer();
var results = xmlDeserializer.Deserialize<Vehicle>(response);
你的类型看起来像:
[XmlRoot("vehicle")]
public class Vehicle
{
[XmlAttribute("found")]
public bool Found { get; set; }
[XmlElement("description")]
public string Description { get; set; }
[XmlElement("buildDate")]
public string BuildDate { get; set; }
[XmlElement("modelYear")]
public string ModelYear { get; set; }
[XmlArray("optionList")]
[XmlArrayItem("option")]
public List<Option> OptionList { get; set; }
}
public class Option
{
[XmlAttribute("code")]
public string Code { get; set; }
[XmlText]
public string Description { get; set; }
}
示例fiddle #3。
答案 1 :(得分:2)
阅读文档:https://github.com/restsharp/RestSharp/wiki/Deserialization
将Description
属性更改为Value
属性,它将起作用(在Option
类中)。
无法给你更好的答案,因为我从未使用过RestSharp:)
答案 2 :(得分:1)
在XML中,您想要的值不是内部XmlElement - 它是当前XmlElement的值。
您可以标记Option
班级&#39; Description
XmlText
属性,而不是XmlElement
。
请参阅related answer。