天天看點

C# WebApi傳參之Post請求-AJAX

   最近悟出來一個道理,在這兒分享給大家:學曆代表你的過去,能力代表你的現在,學習代表你的将來。

   十年河東十年河西,莫欺少年窮。 

   學無止境,精益求精

   上一節講述了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);
        }      

繼續閱讀