How to deserialize xml for a list in RestSharp?
My XML:
<result>
<document version="2.1.0">
<response type="currency">
<currency>
<code>AMD</code>
<price>85.1366</price>
</currency>
</response>
<response type="currency">
<currency>
<code>AUD</code>
<price>31.1207</price>
</currency>
</response>
</document>
</result>
My class:
public class CurrencyData
{
public string Code { get; set; }
public string Price { get; set; }
}
My deserializer:
RestClient.ExecuteAsync<List<CurrencyData>>...
If I renamed the class CurrencyData
to Currency
, everything is done correctly. But I want to keep this class name.
Ok i think i got it
You may try RestClient.ExecuteAsync<Result>()
[XmlRoot("result")]
public class Result
{
[XmlElement("document")]
public Document Document { get; set; }
}
public class Document
{
[XmlElement("response")]
public Response[] Responses { get; set; }
[XmlAttribute("version")]
public string Version { get; set; }
}
public class Response
{
[XmlElement("currency")]
public CurrencyData Currency { get; set; }
[XmlAttribute("type")]
public string Type { get; set; }
}
public class CurrencyData
{
[XmlElement("code")]
public string Code { get; set; }
[XmlElement("price")]
public decimal Price { get; set; }
}
I had to add a few attributes XmlElement
to override the wrapper without specifying lowercase classes and properties. but you can discard them if you can change the xml to match the skin
Then change the xml tag to CurrencyData. Here is the documentation about the xml deserializer: https://github.com/restsharp/RestSharp/wiki/Deserialization
I'm not sure why Kay.one's answer is accepted, it doesn't answer the question.
In my comment, the RestSharp deserializer does not check the attribute by default DeserializeAs
when deserializing the list. I'm not sure if this is intentional or a bug as the author doesn't seem to be very accessible.
This is a simple fix anyway.
private object HandleListDerivative(object x, XElement root, string propName, Type type)
{
Type t;
if (type.IsGenericType)
{
t = type.GetGenericArguments()[0];
}
else
{
t = type.BaseType.GetGenericArguments()[0];
}
var list = (IList)Activator.CreateInstance(type);
var elements = root.Descendants(t.Name.AsNamespaced(Namespace));
var name = t.Name;
//add the following
var attribute = t.GetAttribute<DeserializeAsAttribute>();
if (attribute != null)
name = attribute.Name;
The answer to this question is kay.one ! It works with any comments:
public List<Response> Responses { get; set; }
work
public Response[] Responses { get; set; }
Does not work
AND
[XmlElement("AnyValue")]
this is from the System.Xml.Serialization namespace and doesn't work. Feel free to just delete them. In this example, the attributes and properties of the annotations have the same names and the serializer understands. But the attributes of the right annotation are relative to the RestSharp.Deserializers namespace
[DeserializeAs(Name="AnyXmlValue")]
public string AnyModelValue { get; set; }
How to manage RestSharp deserialization