反序列化XML Rest Web Api调用?

时间:2015-02-11 20:12:50

标签: c# xml asp.net-web-api deserialization

我一直在关注一些在线示例,由于某些原因,我无法成功反序列化以下XML文档:

<?xml version="1.0" encoding="UTF-8"?>
<result>
    <postcode>BD1 1LT</postcode>
    <geo>
        <lat>53.793063240118215</lat>
        <lng>-1.7540318423563699</lng>
        <easting>416300.0</easting>
        <northing>433000.0</northing>
        <geohash>http://geohash.org/gcwf00dz21g1</geohash>
    </geo>
    <administrative>
        <council>
            <title>Bradford</title>
            <uri>http://statistics.data.gov.uk/id/statistical-geography/E08000032</uri>
            <code>E08000032</code>
        </council>
        <ward>
            <title>City</title>
            <uri>http://statistics.data.gov.uk/id/statistical-geography/E05001347</uri>
            <code>E05001347</code>
        </ward>
        <constituency>
            <title>Bradford West</title>
            <uri>http://statistics.data.gov.uk/id/statistical-geography/E14000589</uri>
            <code>E14000589</code>
        </constituency>
    </administrative>
</result>

我尝试过各种各样的组合:

[DataContract(Name = "result", Namespace = "")]
public class Result
{
    [DataMember(Name = "postcode")]
    public string Postcode { get; set; }
    [DataMember(Name = "geo")]
    public Geo Geo { get; set; } 
}

[DataContract(Name = "geo")]
public class Geo
{
    [DataMember(Name = "lat")]
    public string Lat { get; set; } 
}

但我能得到的只是邮政编码,而不是别的。 上面 就是我 工作atm

以下是我根据一些例子汇总的内容:

    [Test]
    public void TestRestCall()
    {
        var url = "http://uk-postcodes.com/postcode/";
        var urlParameters = "bd11lt.xml";
        var client = new HttpClient();
        client.BaseAddress = new Uri(url);

        // Add an Accept header for JSON format.
        client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/xml"));

        // List data response.
        HttpResponseMessage response = client.GetAsync(urlParameters).Result;  // Blocking call!
        if (response.IsSuccessStatusCode)
        {
            // Parse the response body. Blocking!
            var dataObjects = response.Content.ReadAsAsync<Result>().Result;
            //Console.WriteLine("{0}", dataObjects.Geo.);
        }
        else
        {
            Console.WriteLine("{0} ({1})", (int)response.StatusCode, response.ReasonPhrase);
        } 
    }

更新:

Geo属性为null,这就是我可以得到的。

3 个答案:

答案 0 :(得分:5)

我看到有两个问题。一个是排序,另一个是命名空间。

您需要在所有属性和对象上指定顺序,但您还需要在所有属性和对象上指定命名空间。

    [DataContract(Name = "result", Namespace = "")]
    public class Result
    {
        [DataMember(Name = "postcode", Order = 1)]
        public string Postcode { get; set; }

        [DataMember(Name = "geo", Order = 2)]
        public Geo Geo { get; set; }
    }

同样在您的GEO对象上,您必须同时指定映射才能在HttpClient上工作。

    [DataContract(Name = "geo", Namespace = "")]
    public class Geo
    {
        [DataMember(Name = "lat", Order = 1)]
        public string Lat { get; set; }
    }

希望有所帮助。

答案 1 :(得分:3)

这个 是订购的东西,但是您可以使用Result的定义来处理它。除非另有说明,否则DataContractSerializer期望元素按字母顺序排列,而不是类中定义的顺序。但是,您可以使用Order的{​​{1}}属性明确告诉它预期的顺序和发出元素。

DataMember的定义更改为

Result

应该解决您的问题。您可以参考MSDN以获得有关数据协定中排序语义的更完整描述。

根据@LouieBacaj的回答,您还需要将空名称空间添加到[DataContract(Name = "result", Namespace = "")] public class Result { [DataMember(Name = "postcode", Order = 1)] public string Postcode { get; set; } [DataMember(Name = "geo", Order = 2)] public Geo Geo { get; set; } } 类中,以正确反序列化嵌套元素:

Geo

答案 2 :(得分:2)

public string Geo应该是public Geo Geo,不是吗?