2

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 calling:

RestClient.ExecuteAsync<List<CurrencyData>>...

If i renamed class CurrencyData to Currency then all will been done right. But I want to keep this class name.

kay.one
  • 7,622
  • 6
  • 55
  • 74
georgeci
  • 347
  • 5
  • 16
  • The `DeserializeAs` attribute works correctly on a single item, however it doesn't work on a collection. The problem is that the deserializer check for the `DeserializeAs` attribute within the alternate workflow that is used for collections. I was able to get it working with literally 2-3 lines of code in the `HandleListDerivative` method (I took the source of the XmlDeserializer` class on Github and registered it as a custom deserializer with my change). – The Muffin Man Dec 25 '14 at 02:12

4 Answers4

4

Ok, I think I got it,

You can 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 XmlElement attribute to override the casing without having to name classes and properties in lowercase. but you can drop them if you can change the xml to match the casing

kay.one
  • 7,622
  • 6
  • 55
  • 74
  • Ah yes, aliasing. My point below was that the names have to match and the RestSharp guide gives you a rundown on how it does the lookups. – u84six Feb 19 '14 at 00:25
1

Answer of kay.one is perfect! It works with a any remarks:

public List<Response> Responses { get; set; }

works

public Response[] Responses { get; set; }

don`t works

And

[XmlElement("AnyValue")]

it is from System.Xml.Serialization namespace and don`t work. Feel free to just delete them. In this example annotation attributes and properties has same names and serializer understands. But right annotation attributes are from RestSharp.Deserializers namespace

    [DeserializeAs(Name="AnyXmlValue")]
    public string AnyModelValue { get; set; }

How to manage deserialization of RestSharp

Community
  • 1
  • 1
0

Then change the xml tag to CurrencyData. Here is the documentation about the xml deserializer: https://github.com/restsharp/RestSharp/wiki/Deserialization

u84six
  • 4,604
  • 6
  • 38
  • 65
0

I'm not sure why Kay.one's answer is accepted, it doesn't answer the question.

Per my comment, the default RestSharp deserializer doesn't check for the DeserializeAs attribute when deserializing a list. I'm not sure if that's intentional or a mistake as the author doesn't seem to be very available.

Anyways it's a simple fix.

    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 Muffin Man
  • 19,585
  • 30
  • 119
  • 191
  • where do you put this? hoping we don't have to modify the RestSharp library because we're using it in Xamarin... – kenyee Jun 17 '15 at 19:25
  • I'm not sure if it's an oversight or not. I've been away from things for a bit so I'll take a look into it now that I'm back. – Michael Jun 19 '15 at 17:44