最近悟出來一個道理,在這兒分享給大家:學歷代表你的過去,能力代表你的現在,學習代表你的將來。
十年河東十年河西,莫欺少年窮。
學無止境,精益求精
上一節講述了C# WebApi傳參之Get請求-AJAX
本節講述C# WebApi傳參之Post請求-AJAX,說起Ajax針對webApi的Post請求,真的不敢恭維,確實比較怪異,如果你不幸要寫一個Ajax Post請求webApi接口,那麼您還是有必要花點時間看看本篇博客,如果你也遇到了同樣的問題,就不妨在最後給本篇博客點個贊。謝謝
說起Post請求,想必大家都比較熟悉,post請求原理和get請求不一樣,我們知道get請求的參數是通過url來傳遞的,而post請求則是通過http的請求體中傳過來的,WebApi的post請求也需要從http的請求體裡面去取參數。說白了Get請求是通過URL傳遞一組鍵值對,Post請求是發送一個Http請求體。上一節Get請求,我們用到了[FromUri]關鍵字。本節的Post請求,我們將使用另一個關鍵字[FromBoay],上一節結尾我建議大家Get請求時要帶上[FromUri]關鍵字,同理,本節的Post請求,我要建議大家在接收參數時,帶上[FromBody]關鍵字,畢竟養成一個好的習慣不是什麼壞事。
開篇中提到,Ajax Post請求webApi很怪異,那麼它究竟怎麼怪異呢?下面以代碼示范說明:<本文仍舊采用上一節Get請求的實體對象,不知道的博友,請參閱我的上篇博客>
如下:
/// <summary> /// 簡單測試案例 /// </summary> /// <returns></returns> [HttpPost] public string Get() { return "OK"; } /// <summary> /// 通過id獲取特定數據 /// </summary> /// <param name="Id"></param> /// <returns></returns> [HttpPost] public string GetById([FromBody]int Id) { list = list.Where(p => p.Id == Id).ToList(); return JsonHelper.JsonSerializer<List<Person>>(list); }
aJax如下
//無參數請求-簡單示例 $(document).ready(function () { $.ajax({ url: "http://localhost:9953/api/Person/Get", type: "post", contentType: "application/json", dataType: "text", data:{}, success: function (result,status) { if (status == "success") { alert(result); } }, error: function (error) { alert(error); } }); }); //單個參數傳遞- data: {"":"3"}, 這種方式也竟然正確 $(document).ready(function (data) { $.ajax({ url: "http://localhost:9953/api/Person/GetById", type: "post", contentType: "application/json", dataType: "text", data: {Id:"3"}, success: function (result,status) { alert(result) }, error: function (error) { alert(error); } }); });
上文JS中注釋有這麼一句話:‘data: {"":"3"}, 這種方式也竟然正確’
這是一種另許多人頭痛的寫法,但是沒辦法,經過測試,這種寫法確實很正確。
根據上述案例,我們看到了Post請求傳遞單個參數的寫法,那麼如果傳遞多個參數,我們能否采取如下的方法?(經測試,如下寫法是錯誤的,報404Not Found)
$(document).ready(function (data) { $.ajax({ url: "http://localhost:9953/api/Person/GetByIdAndSex", type: "post", contentType: "application/json", dataType: "text", data: { Id: "3",Sex:"W" }, success: function (result, status) { alert(result) }, error: function (error) { alert(error); } }); });
/// <summary> /// 錯誤的寫法 當然,本篇只講解Ajax請求,如果你是通過HttpwebClient的方式進行請求,這種寫法是沒有任何問題的 /// </summary> /// <param name="Json"></param> /// <returns></returns> [HttpPost] public HttpResponseMessage GetByIdAndSex([FromBody]string Id,[FromBody]string Sex) { List<Person> list_2 = new List<Person>(); var Result = from r in list where r.Id == Convert.ToInt32(Id) && r.Sex == Sex select r; foreach (var Item in Result) { list_2.Add(Item); } return ResultToJson.toJson(list_2); }
測試的結果是:獲取不到Id 和 Sex 的值!開篇我們說到,Get的請求方式是通過URL傳遞鍵值對,而Post 請求傳遞的是一個Http請求體,而JS中 data: { Id: "3",Sex:"W" }, 采用的是鍵值對類型,而Post請求是不能讀取鍵值對滴。故:上述寫法不對。
那麼,你可能會問,為什麼一個參數請求的時候沒有問題,為什麼兩個參數就不行了呢?這個...我能作的解答是:這就是Post Ajax請求的怪異之處。
正確的寫法該當如何呢?
我們知道:Get請求傳遞兼職對,Post請求傳遞的是Http的請求體,按照本人的理解就是:Post請求需要發送一個參數作為Http請求體,這個參數為一個整體,而非一組鍵值對、故而,我們作如下改動:
代碼如下:
//多個參數傳遞 $(document).ready(function (data) { $.ajax({ url: "http://localhost:9953/api/Person/GetByIdAndSex", type: "post", contentType: "application/json", dataType: "text", data: JSON.stringify({ Id: "3",Sex:"W" }), success: function (result, status) { alert(result) }, error: function (error) { alert(error); } }); });
/// <summary> /// 錯誤的寫法2 怪異吧 /// </summary> /// <param name="Json"></param> /// <returns></returns> [HttpPost] public HttpResponseMessage GetByIdAndSex([FromBody]string Json) { string Id = JsonHelper.GetJsonValue(Json, "Id");//獲取Id string Sex = JsonHelper.GetJsonValue(Json, "Sex");//獲取sex List<Person> list_2 = new List<Person>(); var Result = from r in list where r.Id == Convert.ToInt32(Id) && r.Sex == Sex select r; foreach (var Item in Result) { list_2.Add(Item); } return ResultToJson.toJson(list_2); }
如上注釋為紅色加粗的JS代碼,我們將Post的鍵值對轉化為Json字符串傳遞到後端。而後端代碼中,我們嘗試接收這個JSon字符串,並作解析,從中讀出Id和Sex的值,按照Post請求規則,我們也是只發送了一個Http請求體,並且在後端作了接收。這次應該沒有問題了吧?
實際測試的結果是:不會發生404 Not Found 錯誤,但是接收不到Post的字符串,也就是 [FromBody]string Json 中的Json為Null,(⊙o⊙)…
靠,這樣都不行,那到底怎麼能行呢?
下班了,不多噴了,直接告訴大家幾點注意事項:
後端接收時,參數類型應采用dynamic,JS代碼中,必須加上contentType對應的類型,Post的值必須為一個整體,而不能是鍵值對。JS中Type類型必須為Post ,後端接收類型必須為:[HttpPost],如果不加,則會默認為[HttpGet]方式。
以下是代碼示例,希望能幫助大家:
1、多個參數傳遞:
//多個參數傳遞 $(document).ready(function (data) { $.ajax({ url: "http://localhost:9953/api/Person/GetByIdAndSex", type: "post", contentType: "application/json", dataType: "text", data: JSON.stringify({ Id: "3",Sex:"W" }), success: function (result, status) { alert(result) }, error: function (error) { alert(error); } }); });
[HttpPost] public HttpResponseMessage GetByIdAndSex([FromBody]dynamic Json) { string Id = Json.Id; string Sex = Json.Sex; List<Person> list_2 = new List<Person>(); var Result = from r in list where r.Id == Convert.ToInt32(Id) && r.Sex == Sex select r; foreach (var Item in Result) { list_2.Add(Item); } return ResultToJson.toJson(list_2); }
2、傳遞一個對象數據
//傳遞對象數組 $(document).ready(function (data) { var dataList = [{ Id: "8888", Sex: "男", Name: "陳臥龍", Age: "26" }, { Id: "8887", Sex: "男", Name: "陳大龍", Age: "27" }, { Id: "8886", Sex: "男", Name: "陳小龍", Age: "25" }]; $.ajax({ url: "http://localhost:9953/api/Person/GetByObjectList", type: "post", contentType: "application/json", dataType: "text", data: JSON.stringify(dataList), success: function (result, status) { alert(result) }, error: function (error) { alert(error); } }); });
/// <summary> /// 對象數組作為參數 /// </summary> /// <param name="P"></param> /// <returns></returns> [HttpPost] public HttpResponseMessage GetByObjectList([FromBody]dynamic Plist) { List<Person> list = new List<Person>(); foreach (var item in Plist) { Person person = new Person() { Name = item.Name, Sex = item.Sex, Id = item.Id, Age = item.Age, }; list.Add(person); } return ResultToJson.toJson(list); }
到此為止:pOst請求也就講完了
我們知道有四大請求:Get,Post,Put,Delete ,其中Put、delete請求都是采用的Post請求原理,他們直接大同小異,無非就是Put請求做修改 插入,Delete請求作刪除。因此:Put Delete 請求均可采用本文中的請求方式,只是他們所作的動作不一樣罷了!
好了,回家清蒸魚喽,最近學的拿手好菜,有喜歡的,歡迎品嘗,我們你們郵遞!哈哈
@陳臥龍的博客