【问题标题】:Unable to deserialize list in a XML Response using ReadAsAsync<T>无法使用 ReadAsAsync<T> 反序列化 XML 响应中的列表
【发布时间】:2019-07-28 15:22:58
【问题描述】:

[更新:这个问题与建议的重复问题不同,因为这个问题是关于 XML 的反序列化,并且由于我已经包含了完整的源代码,所以对这个问题和解决方案的解释更加清晰。]

我正在尝试读取并随后处理来自 Web API 的响应。它的响应如下所示:

<MYAPI xsi:noNamespaceSchemaLocation="MYAPI.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
   <MySite Resource="some resource name">
       <Name>some name</Name>
       <URL>some url</URL>
       <SecondName>Describes something</SecondName>
   </MySite>
   ... A lot of these <MySite>...</MySite> are there         

   <SomeOtherSite Resource="some resource name">
       <Name>some name</Name>
       <URL>some url</URL>
   </SomeOtherSite>
</MYAPI>

SomeOtherSite 没有重复,只有一个出现在响应的末尾。但是MySite 是重复的。 我已将此 XML 响应的类建模为:

public class MYAPI
{
    public List<MySite> MySite { get; set; }
    public SomeOtherSite SomeOtherSite { get; set; }
}

public class MySite
{
    public string Name { get; set; }
    public string URL { get; set; }
    public string SecondName { get; set; }
}

public class SomeOtherSite
{
    public string Name { get; set; }
    public string URL { get; set; }
}

这是我的代码:

static void Main()
{
    var handler = new HttpClientHandler();
    handler.Credentials = new NetworkCredential("MyUsername", "MyPassword");

    var client = new HttpClient(handler);
    client.BaseAddress = new Uri("https://sitename.com:PortNumber/");

    var formatters = new List<MediaTypeFormatter>() 
    {
        new XmlMediaTypeFormatter(){ UseXmlSerializer = true } 
    };

    var myApi = new MYAPI();
    HttpResponseMessage response = client.GetAsync("/api/mysites").Result;

    if (response.IsSuccessStatusCode)
    {

        myApi = response.Content.ReadAsAsync<MYAPI>(formatters).Result;
    }
}

现在myApi 只有SomeOtherSite 的对象,但MySite 的列表为空。 有人能告诉我应该如何正确反序列化这个响应吗? 我应该创建自定义媒体格式化程序吗?顺便说一句,我不知道。

另外请告诉我如何为响应中的Resource 属性建模?

而且我无法更改 WebAPI 服务器中的任何内容。我只需要使用其中的数据并在其他地方使用它。

非常感谢!

【问题讨论】:

  • 关于List&lt;MySite&gt; 的问题,请尝试查看here。至于Resource 属性,您应该可以使用 XmlAttributeAttribute 参见here
  • 我为你建立了一个简单的例子here
  • XML serialization of list的可能重复

标签: c# rest asp.net-web-api httpclient xml-serialization


【解决方案1】:

在从https://stackoverflow.com/users/1124565/amura-cxg 获得了一些非常好的指导后,我解决了这个问题,非常感谢!

解决方案是使用 XMLAttributes 注释所有属性。它正确地反序列化了响应。至于Resource 属性,我只需要[XmlAttribute(AttributeName="Resource")]

源代码的其余部分按原样工作。

[XmlRoot(ElementName="MYAPI")]
public class MYAPI 
{
    [XmlElement(ElementName="MySite")]
    public List<MySite> MySite { get; set; }

    [XmlElement(ElementName="SomeOtherSite")]
    public SomeOtherSite SomeOtherSite { get; set; }
}

public class MySite 
{
    [XmlElement(ElementName="Name")]
    public string Name { get; set; }

    [XmlElement(ElementName="URL")]
    public string URL { get; set; }

    [XmlElement(ElementName="SecondName")]
    public string SecondName { get; set; }

    [XmlAttribute(AttributeName="Resource")]
    public string Resource { get; set; }
}

另外,我不需要任何自定义媒体格式化程序。从https://stackoverflow.com/users/1855967/elisabeth 的一篇帖子中,我了解到我们不应该接触从 xsd.exe 工具生成的文件。所以我明确设置使用XmlSerializer,而不是默认使用的DataContractSerializer

var formatters = new List<MediaTypeFormatter>() 
    {
        new XmlMediaTypeFormatter(){ UseXmlSerializer = true } 
    };

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-02-08
    • 2012-01-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多