我第一次寫入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