【发布时间】:2012-09-03 23:50:57
【问题描述】:
我第一次尝试使用 ASP.NET Web API,但我遇到了一个让我非常沮丧的问题。
我调用的 RESTful 服务返回如下数据:
<SearchResults xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
<Results>
<Result>
<Title>foo</Title>
</Result>
<Result>
<Title>bar</Title>
</Result>
</Results>
<NumberOfResults>2</NumberOfResults>
</SearchResults>
所以我创建了一些实体来表示这些数据:
[Serializable, DataContract(Namespace = "")]
public class SearchResults
{
public List<Result> Results { get; set; }
public int NumberOfResults { get; set; }
}
[Serializable, DataContract(Namespace = "")]
public class Result
{
public string Title { get; set; }
}
然后我尝试反序列化数据:
var client = new HttpClient();
client.BaseAddress = new Uri("some uri");
var response = client.GetAsync("/some/path/").Result;
response.EnsureSuccessStatusCode();
var result = response.Content.ReadAsAsync<SearchResults>().Result;
这会导致 SearchResults 对象的 Results = null 和 NumberOfResults = 0,即使我知道有结果被返回,并且如果我检查 response.Content.ReadAsStringAsync(),XML 包含预期的结果。
我改为尝试:
var serializer = new XmlSerializer(typeof(SearchResults));
var results = (SearchResults)serializer.Deserialize(response.Content.ReadAsStreamAsync().Result);
这会返回一个完全填充的 SearchResults 对象。
最后,我尝试实现一个简单的 IFormatterLogger 并将其传递给 ReadAsAsync,如果我尝试读取流两次(正如预期的那样!),它会被调用,但在使用 ReadAsAsync 进行反序列化的标准尝试期间不会被调用。
我可以只使用 XmlSerializer 并将其传递给它,因为它有效,但这似乎不像使用 ReadAsAsync 那样整洁,而且我真的想知道我做错了什么:)
2012 年 3 月 9 日英国夏令时 16:38 更新
好吧,我在使用 Web API 时显然遗漏了一些至关重要的东西,但我仍然不知道是什么!
我现在尝试使用带有 PUT 动词的服务,当我使用 XmlSerializer 对其进行测试时,我的实体可以正确序列化,但请求失败并显示 HTTP 500。我检查了 Fiddler 发送的内容和生成的 XML Web API 看起来与 XmlSerializer 生成的完全不同。首先,所有东西都有像“_x003C_Name_x003E_k__BackingField”这样的名称,而不是简单的“名称”。
【问题讨论】:
-
猜测,您可能正在使用不同的序列化程序。 XML 看起来像是 WCF XML(即 DataContractSerializer)还是 XmlSerializer?您可能需要考虑使用 JSON,因为序列化/反序列化和减小数据包大小会更快。
-
不幸的是,我对服务端代码没有任何控制权,它只支持 XML,所以 JSON 不是一个选项。我认为它可能是另一端的 WCF,但不能确定。当然,另一边的技术应该无关紧要吗?如问题中所述,XmlSerializer 对接收到的数据进行反序列化没有问题。
-
啊,那肯定是 WCF。 WCF 具有具有该支持字段属性名称的代理类。因为您使用的是 WCF,所以它与 WebAPI 的堆栈不同,因此使用 ReadAsAsync 进行序列化/反序列化并不容易。猜测您将不得不恢复使用映射器将您的 XML 转换为 POCO。 (编辑:看这里integratedwebsystems.com/2009/05/…)
标签: c# asp.net-web-api