简体   繁体   English

反序列化XML Rest WebApi调用?

[英]Deserialize XML Rest WebApi Call?

I have been following some online examples and for some reason I cannot successfully deserialize the following XML document: 我一直在关注一些在线示例,由于某些原因,我无法成功反序列化以下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>

I've tried all sorts of combinations: 我尝试了各种组合:

[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; } 
}

But all I can get is the post code and nothing else. 但是我所能获得的只是邮政编码,没有别的。 Above is what I have working atm . 以上 是我 在atm工作的内容

Below is what I have put together following some examples: 以下是我整理的一些示例:

    [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);
        } 
    }

UPDATE: 更新:

The Geo property is null and that's as far as I can get with this. Geo属性为null,这是我所能获得的。

There are two problems that I see. 我看到两个问题。 One is with the ordering and another is with namespace. 一种是排序,另一种是命名空间。

You need to specify the order on all of your properties and objects but you also need to specify the namespace on all of them. 您需要在所有属性和对象上指定顺序,但是还需要在所有属性和对象上指定名称空间。

    [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; }
    }

Likewise on your GEO object you have to specify both for the mapping to work on the HttpClient. 同样,在您的GEO对象上,您必须同时指定两个映射才能在HttpClient上工作。

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

Hope that helps. 希望能有所帮助。

This is an ordering thing, but it's one you can work around with your definition of Result . 一件事,但您可以使用Result的定义来解决。 DataContractSerializer , unless told otherwise, expects elements to be in alphabetical order, not the order defined in the class. 除非另有说明,否则DataContractSerializer期望元素按字母顺序,而不是类中定义的顺序。 But, you can use the Order property of DataMember to explicitly tell it in what order to expect and emit elements. 但是,您可以使用DataMemberOrder属性以明确的方式告诉它期望和发出元素的顺序。

Changing your definition of Result to 将您对Result的定义更改为

[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; }
}

should fix your issue. 应该解决您的问题。 You can refer to MSDN for a more complete description of ordering semantics in data contracts. 您可以参考MSDN ,以获得关于数据协定中排序语义的更完整描述。

As per @LouieBacaj's answer, you will also need to add the empty namespace to your Geo class to correctly deserialze the nested element: 按照@LouieBacaj的回答,您还需要将空名称空间添加到您的Geo类中,以正确反序列化嵌套元素:

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

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM