2012-09-03 79 views
2

我第一次写入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”。

+0

猜测,您可能正在使用不同的序列化程序。 XML看起来像是WCF XML(即DataContractSerializer)还是XmlSerializer? 您可能需要考虑使用JSON,因为序列化/反序列化和减少数据包大小会更快。 – leon

+0

不幸的是,我没有任何控制服务端代码,它只支持XML,所以JSON不是一个选项。我认为它可能是WCF的另一端,但不能确定。另一方面的技术当然应该是无关紧要的?如问题所述,XmlSerializer对接收到的数据进行反序列化没有问题。 – VaticanUK

+0

Ahh yeh - 那肯定是WCF了。 WCF具有包含该支持字段属性名称的代理类。因为您使用的是WCF,所以它与WebAPI是不同的堆栈,因此使用ReadAsAsync时序列化/反序列化不会很容易。猜测您必须恢复使用映射器来将您的XML转换为POCO。 (编辑:看这里http://www.integratedwebsystems.com/2009/05/wcf-data-contracts-and-k__backingfield-property-naming/) – leon

回答

0

从我的更新怪异的“k__BackingField”名称导致我的决议,并像往常一样,它是非常简单的。

我忘了使用DataMemberAttribute标记实体中的属性。

标记起来,它开始工作,因为我原本以为它!

就是这样!

+1

对我来说ReadAsAsync 无法反序列化具有[Serializable]属性的类,删除属性反序列化后按预期工作。 – neo112