我有一個ASP.NET MVC4網站實現一個REST API,我從客戶端應用程序中使用它。我的ApiController方法接收和返回複雜的對象,如XML。如何使用RestSharp POST(作爲XML)對象到我的ApiController?
我最近發現了RestSharp,並開始將我的客戶項目移到那個。但是,我遇到了實際問題。看起來差不多工作 - 這是如此接近,我幾乎可以品嚐成功 - 但我不能讓它工作100%。
我橫穿線的對象是這個樣子:
// The object I'm passing across the wire
public class Example
{
bool IsActive { get; set; }
string Name { get; set; }
}
我ApiController方法是這樣的:
// My ApiController method
public HttpResponseMessage PostExample(Example example)
{
if (ModelState.IsValid)
{
db.Examples.Add(example);
db.SaveChanges();
HttpResponseMessage response = Request.CreateResponse(HttpStatusCode.Created, example);
return response;
}
else
{
return Request.CreateResponse(HttpStatusCode.BadRequest);
}
}
,當我嘗試發佈一個對象時出現問題我的網站,像這樣:
var example = new Example() { IsActive = true, Name = "foo" };
var request = new RestSharp.RestRequest("/api/example", RestSharp.Method.POST);
request.AddBody(example, XmlNamespace);
var client = new RestClient();
client.BaseUrl = "foo.com";
var response = client.Execute<Example>(request);
上面的代碼確實打擊了PostExample方法我在我的ApiController中,它有一個Example對象作爲參數。 但是 Example對象的屬性值不同於我傳遞給Execute方法的值!在一個案例中,IsActive成員是錯誤的,而不是真實的,儘管我還看到一個名稱成員爲null的情況,它應該有一個值。
我使用Fiddler做了一些調查,看起來正確值是在RestSharp生成的XML中創建的。但是,XML的格式與Web服務器在執行GET時發出的格式不完全相同。差異是微妙的,但似乎使它的工作和不工作的區別。 Web服務器端的框架似乎對這些格式差異很敏感,並且導致錯誤解釋XML。
這裏的XML我從RestSharp得到:
<Example xmlns="http://schemas.datacontract.org/2004/07/ExampleNamespace">
<Name>foo</Name>
<IsActive>true</IsActive>
</Example>
這是我獲得的網絡服務器做一個GET(或使用DataContractSerializer的,這是我以前在做的時候序列化)時:
<Example xmlns:i="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://schemas.datacontract.org/2004/07/ExampleNamespace">
<IsActive>true</IsActive>
<Name>foo</Name>
</TagDto>
的RestSharp版本有從DataContractSerializer的的版本有以下區別:
- 個字段是按不同的順序
- RestSharp不包括額外的命名空間XMLSchema的實例命名空間
- 的DataContractSerializer不包括任何空格或換行符(我加了上面那些可讀性)
我很驚訝,其中任何一個都有很大的不同,但顯然他們確實如此。還要注意的是,除非在AddBody調用中添加了顯式名稱空間,否則在生成的XML(顯然)中缺少該名稱空間,並且傳入我的ApiController的Example對象爲null
。
無論如何,我注意到RestSharp允許您重寫序列化程序,並提供了一種使用.NET XML序列化程序的方法。我嘗試使用(無濟於事)。
這是我的呼籲AddBody之前添加:
request.XmlSerializer = new RestSharp.Serializers.DotNetXmlSerializer(XmlNamespace);
..和這是我出去:
<?xml version="1.0" encoding="utf-8"?>
<Example>
<Name>foo</Name>
<IsActive>true</IsActive>
</Example>
這顯然是不行的,因爲它沒有啓動至少用XML聲明,我想會導致問題。沒有辦法關閉它,因爲RestSharp派生類沒有辦法這樣做。此外,沒有命名空間 - 無論我如何嘗試在RestSharp中設置命名空間(在DotNetXmlSerializer的構造函數中,通過設置命名空間成員,或通過將名稱空間傳遞給AddBody)。在我看來,這門課不過是一個陷阱。
它看起來像我唯一的選擇是創建我自己的串行器類,並在內部使用DataContractSerializer。那是對的,還是我錯過了什麼? (順便說一下,我可以將請求的RequestFormat設置爲JSON,它只是起作用 - 但我仍然想知道如何使用XML進行操作)。
它是一個必須爲你使用RestSharp修改格式化? – 2012-08-16 11:44:59
@CongLe:哈!我最初使用DataContractSerializer開始自己編寫,然後被同事說服使用RestSharp。我可以切換到另一種解決方案,但我現在花了很多時間試圖讓RestSharp工作,我不願意這樣做。正如我在答覆中暗示的那樣,我最終轉而使用JSON而不是XML,所以這個問題仍然主要是爲了其他人的利益。 – 2012-08-16 12:35:22
@Gary,我認爲JSON就是像RESTSharp這樣的庫,它的性能也非常出色,你在性能方面也會獲得小的性能提升。 – leon 2012-08-20 08:21:35