接著上一篇部落格的內容做一個補充,正好是一個大哥提出來的,我們看看一個有趣的現象。
請求相關問題的補充:
我們先在Controller中的定義一個我們在前一篇部落格中已經測試過的方法如下:
public class DemoController : ApiController { [HttpGet] public HttpResponseMessage InsertPerson(string name,int age) { return this.Request.CreateResponse(HttpStatusCode.OK); } [HttpGet] public HttpResponseMessage InsertPlant(string name, int height) { return this.Request.CreateResponse(HttpStatusCode.OK); } }
經過上一篇文章的測試,使用Get api/Demo/InsertPseron?name=halower&age=18請求這個方法No problem !然後我們將其替換成[HttpPost]方式如下:
public class DemoController : ApiController { [HttpPost] public HttpResponseMessage InsertPerson(string name,int age) { return this.Request.CreateResponse(HttpStatusCode.OK); } [HttpPost] public HttpResponseMessage InsertPlant(string name, int height) { return this.Request.CreateResponse(HttpStatusCode.OK); } }
現在我們開始操刀測試,結果情理之中,意料之外,注意的是我們在使用Fiddler測試的時候,請求頭中需要新增:Content-Length:0,否則報錯其它哦,當我們如下使用 Post api/Demo/InsertPseron請求時,發現根本找不到資源
可能你會這麼認為是因為沒有傳入引數值,所以會找不到相應的Action,那麼我們就截獲它的請求給它傳入引數值試試:
結果還是411,嘗試失敗了,這是因為WebAPI對於Get和Post的處理機制不一樣,那麼我們就嘗試著解決這個問題
解決方法
方法一:使用DTO類進行資料的包裝
我們將請求的資料分裝成2個DTO類後進行物件的傳遞如下:
public class Person { public string Name { get; set; } public int Age { get; set; } } public class Plant { public string Name { get; set; } public int Height { get; set; } } public class DemoController : ApiController { [HttpPost] public HttpResponseMessage InsertPerson(Person person) { return this.Request.CreateResponse(HttpStatusCode.OK); } [HttpPost] public HttpResponseMessage InsertPlant(Plant plant) { return this.Request.CreateResponse(HttpStatusCode.OK); } }
我們在測試一下:
結果是500,但是我們在Fidder的TextView中異常資訊,發現找到了多個Action方法,毫不猶豫我們修要修改路由了
config.Routes.MapHttpRoute( name: "", routeTemplate: "api/{controller}/{action}/{id}", defaults: new { action = RouteParameter.Optional, id = RouteParameter.Optional } ); config.Routes.MapHttpRoute( name: "DefaultApi", routeTemplate: "api/{controller}/{id}", defaults: new {id = RouteParameter.Optional }
修改後我們在測試一次試試,OK了:
方法二:使用FormCollection
using System.Net; using System.Net.Http; using System.Web.Http; using System.Web.Mvc; namespace WebAPI.Controllers { public class DemoController : ApiController { [System.Web.Http.HttpPost] public HttpResponseMessage InsertPerson(FormCollection person) { return this.Request.CreateResponse(HttpStatusCode.OK); } [System.Web.Http.HttpPost] public HttpResponseMessage InsertPlant(FormCollection plant) { return this.Request.CreateResponse(HttpStatusCode.OK); } } }
測試結果:
注意:我們可能參考官方的模板,使用FromBodyAttribute,做出這樣的錯誤(可以點選這裡檢視該問題的具體細節和解釋):
[HttpPost] public HttpResponseMessage InsertPerson([FromBody] string name,[FromBody]string age) { return this.Request.CreateResponse(HttpStatusCode.OK); }
方法三:使用 Newtonsoft.Json.Linq名稱空間下的中的 JObject
using Newtonsoft.Json.Linq; using System.Net; using System.Net.Http; using System.Web.Http; namespace WebAPI.Controllers { public class DemoController : ApiController { [HttpPost] public HttpResponseMessage InsertPerson(JObject person) { return this.Request.CreateResponse(HttpStatusCode.OK); } [HttpPost] public HttpResponseMessage InsertPlant(JObject plant) { return this.Request.CreateResponse(HttpStatusCode.OK); } } }
執行效果:
未完待續....之後將對oData的支援,多媒體支援,Jquery呼叫WEB API等進行筆記總結。
備註:我也是剛剛開始學習,參閱了很多前輩的文章,所以版權的歸大家所有,不歸本人所有,如果你喜歡本文的話,推薦共勉,謝謝!