无法使用 ReadAsAsync<T> 反序列化 XML 响应中的列表
Unable to deserialize list in a XML Response using ReadAsAsync<T>
[更新:这个问题与建议的重复问题不同,因为这个问题是关于 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 响应的 class 建模为:
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 服务器中的任何内容。我只需要使用它的数据并在其他地方使用它。
非常感谢!
我在一些非常好的指导下解决了这个问题:https://whosebug.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://whosebug.com/users/1855967/elisabeth 的一篇帖子中,我了解到我们不应该触及 xsd.exe 工具生成的文件。所以我明确设置使用 XmlSerializer
而不是默认使用的 DataContractSerializer
:
var formatters = new List<MediaTypeFormatter>()
{
new XmlMediaTypeFormatter(){ UseXmlSerializer = true }
};
[更新:这个问题与建议的重复问题不同,因为这个问题是关于 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 响应的 class 建模为:
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 服务器中的任何内容。我只需要使用它的数据并在其他地方使用它。
非常感谢!
我在一些非常好的指导下解决了这个问题:https://whosebug.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://whosebug.com/users/1855967/elisabeth 的一篇帖子中,我了解到我们不应该触及 xsd.exe 工具生成的文件。所以我明确设置使用 XmlSerializer
而不是默认使用的 DataContractSerializer
:
var formatters = new List<MediaTypeFormatter>()
{
new XmlMediaTypeFormatter(){ UseXmlSerializer = true }
};