我第一次写入ASP.NET Web API时遇到了一个问题,这导致了我很大的挫折感。ASP.NET Web API ReadAsAsync失败,没有错误
那我打电话的回报,如数据的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和Number OfResults = 0,即使我知道有结果被返回,并且如果我检查response.Content.ReadAsStringAsync(),则XML包含按预期的结果。
我不是尝试:
var serializer = new XmlSerializer(typeof(SearchResults));
var results = (SearchResults)serializer.Deserialize(response.Content.ReadAsStreamAsync().Result);
而这回完全填充的SearchResult所反对。
最后,我想实现一个简单的IFormatterLogger并传递到这ReadAsAsync,如果我试图读取流这两次接到电话(如预期!),但在反序列化使用ReadAsAsync标准的尝试过程中不会被调用。
我可以只使用一个XmlSerializer,并通过它的蒸汽,因为这样的作品,但似乎并不干净整洁的使用ReadAsAsync,再加上我真的想知道我在做什么错:)
已更新16:38BST 03/09/2012
好的,我明显错过了使用Web API时至关重要的一些事情,但我仍然不知道该怎么做!
我已经尝试使用PUT动词消费服务,而当我使用XmlSerializer测试它时,我的实体正确序列化,请求失败,出现HTTP 500.我检查了使用Fiddler发送的内容以及生成的XML通过Web API看起来没有像XmlSerializer生成的那样。一开始,everthing的名称就像“_x003C_Name_x003E_k__BackingField”,而不是简单的“Name”。
猜测,您可能正在使用不同的序列化程序。 XML看起来像是WCF XML(即DataContractSerializer)还是XmlSerializer? 您可能需要考虑使用JSON,因为序列化/反序列化和减少数据包大小会更快。 – leon
不幸的是,我没有任何控制服务端代码,它只支持XML,所以JSON不是一个选项。我认为它可能是WCF的另一端,但不能确定。另一方面的技术当然应该是无关紧要的?如问题所述,XmlSerializer对接收到的数据进行反序列化没有问题。 – VaticanUK
Ahh yeh - 那肯定是WCF了。 WCF具有包含该支持字段属性名称的代理类。因为您使用的是WCF,所以它与WebAPI是不同的堆栈,因此使用ReadAsAsync时序列化/反序列化不会很容易。猜测您必须恢复使用映射器来将您的XML转换为POCO。 (编辑:看这里http://www.integratedwebsystems.com/2009/05/wcf-data-contracts-and-k__backingfield-property-naming/) – leon