ajax參數傳遞之[HttpGet]/[HttpPost]/[HttpPut]/[HttpDelete]請求

$.ajax({ type: "get", url: "http://localhost:27221/api/Charging/GetByModel", contentType: "application/json", data: { ID: "1", NAME: "Jim", CREATETIME: "1988-09-11" }, success: function (data, status) { if (status == "success") { $("#div_test").html(data); } } });html

複製代碼

       [HttpGet]
        public string GetAllChargingData([FromUri]TB_CHARGING obj)
        {
            return "ChargingData" + obj.ID;
        }

獲得結果:前端

 

若是你不想使用[FromUri]這些在參數裏面加特性的這種「怪異」寫法,也能夠採用先序列化,再在後臺反序列的方式。web

複製代碼

  $.ajax({
        type: "get",
        url: "http://localhost:27221/api/Charging/GetByModel",
        contentType: "application/json",
        data: { strQuery: JSON.stringify({ ID: "1", NAME: "Jim", CREATETIME: "1988-09-11" }) },
        success: function (data, status) {
            if (status == "success") {
                $("#div_test").html(data);
            }
        }
    });

複製代碼

複製代碼

        [HttpGet]
        public string GetByModel(string strQuery)
        {
            TB_CHARGING oData = Newtonsoft.Json.JsonConvert.DeserializeObject<TB_CHARGING>(strQuery);
            return "ChargingData" + oData.ID;
        }

複製代碼

這樣在後臺獲得咱們序列化過的對象,再經過反序列化就能獲得對象。ajax

 

數組做爲參數

通常get請求不建議將數組做爲參數,由於咱們知道get請求傳遞參數的大小是有限制的,最大1024字節,數組裏面內容較多時,將其做爲參數傳遞可能會發生參數超限丟失的狀況。json

 

 

複製代碼

    $.ajax({
        type: "get",
        url: "http://localhost:27221/api/Charging/FindByModel",
        contentType: "application/json",
        data: { strQuery: JSON.stringify({ ID: "1", NAME: "Jim", CREATETIME: "1988-09-11" }) },
        success: function (data, status) {
            if (status == "success") {
                $("#div_test").html(data);
            }
        }
    });

複製代碼

複製代碼

        [HttpGet]
        public string FindByModel(string strQuery)
        {
            TB_CHARGING oData = Newtonsoft.Json.JsonConvert.DeserializeObject<TB_CHARGING>(strQuery);
            return "ChargingData" + oData.ID;
        }

複製代碼

方法名以Get開頭,WebApi會自動默認這個請求就是get請求,而若是你以其餘名稱開頭而又不標註方法的請求方式,那麼這個時候服務器雖然找到了這個方法,可是因爲請求方式不肯定,因此直接返回給你405——方法不被容許的錯誤。後端

最後結論:全部的WebApi方法最好是加上請求的方式([HttpGet]/[HttpPost]/[HttpPut]/[HttpDelete]),不要偷懶,這樣既能防止相似的錯誤,也有利於方法的維護,別人一看就知道這個方法是什麼請求。api

2、post請求

在WebApi的RESETful風格里面,API服務的增刪改查,分別對應着http的post/delete/put/get請求。咱們下面就來講說post請求參數的傳遞方式。數組

一、基礎類型參數

 post請求的基礎類型的參數和get請求有點不同,咱們知道get請求的參數是經過url來傳遞的,而post請求則是經過http的請求體中傳過來的,WebApi的post請求也須要從http的請求體裏面去取參數。服務器

(1)錯誤的寫法

複製代碼

    $.ajax({
        type: "post",
        url: "http://localhost:27221/api/Charging/SaveData",
        data: { NAME: "Jim" },
        success: function (data, status) {
            if (status == "success") {
                $("#div_test").html(data);
            }
        }
    });

        [HttpPost]
        public bool SaveData(string NAME)
        {
            return true;
        }

複製代碼

這是一種看上去很是正確的寫法,但是實際狀況是:app

(2)正確的用法

複製代碼

    $.ajax({
        type: "post",
        url: "http://localhost:27221/api/Charging/SaveData",
        data: { "": "Jim" },
        success: function (data, status) {}
    });

        [HttpPost]
        public bool SaveData([FromBody]string NAME)
        {
            return true;
        }

複製代碼

這是一種另許多人頭痛的寫法,可是沒辦法,這樣確實能獲得咱們的結果:

咱們通常的經過url取參數的機制是鍵值對,即某一個key等於某一個value,而這裏的FromBody和咱們通常經過url取參數的機制則不一樣,它的機制是=value,沒有key的概念,而且若是你寫了key(好比你的ajax參數寫的{NAME:"Jim"}),後臺反而獲得的NAME等於null。不信你能夠試試。

上面講的都是傳遞一個基礎類型參數的狀況,那麼若是咱們須要傳遞多個基礎類型呢?按照上面的推論,是否能夠([FromBody]string NAME, [FromBody]string DES)這樣寫呢。試試便知。

(1)錯誤寫法

複製代碼

    $.ajax({
        type: "post",
        url: "http://localhost:27221/api/Charging/SaveData",
        data: { "": "Jim","":"備註" },
        success: function (data, status) {}
    });

        [HttpPost]
        public bool SaveData([FromBody]string NAME, [FromBody] string DES)
        {
            return true;
        }

複製代碼

獲得結果

這說明咱們沒辦法經過多個[FromBody]裏面取值,此法失敗。

(2)正確用法

既然上面的辦法行不通,那咱們如何傳遞多個基礎類型的數據呢?不少的解決辦法是新建一個類去包含傳遞的參數,博主以爲這樣不夠靈活,由於若是咱們先後臺每次傳遞多個參數的post請求都去新建一個類的話,咱們系統到時候會有多少個這種參數類?維護起來那是至關的麻煩的一件事!因此博主以爲使用dynamic是一個很不錯的選擇。咱們來試試。

複製代碼

    $.ajax({
        type: "post",
        url: "http://localhost:27221/api/Charging/SaveData",
        contentType: 'application/json',
        data: JSON.stringify({ NAME: "Jim",DES:"備註" }),
        success: function (data, status) {}
    });

        [HttpPost]
        public object SaveData(dynamic obj)
        {
            var strName = Convert.ToString(obj.NAME);
            return strName;
        }

複製代碼

經過dynamic動態類型能順利獲得多個參數,省掉了[FromBody]這個累贅,而且ajax參數的傳遞不用使用"無厘頭"的{"":"value"}這種寫法,有沒有一種小清新的感受~~有一點須要注意的是這裏在ajax的請求裏面須要加上參數類型爲Json,即 contentType: 'application/json', 這個屬性。

經過上文post請求基礎類型參數的傳遞,咱們瞭解到了dynamic的方便之處,爲了不[FromBody]這個累贅和{"":"value"}這種"無厘頭"的寫法。博主推薦全部基礎類型使用dynamic來傳遞,方便解決了基礎類型一個或多個參數的傳遞,示例如上文

 

二、實體做爲參數

(1)單個實體做爲參數

上面咱們經過dynamic類型解決了post請求基礎類型數據的傳遞問題,那麼當咱們須要傳遞一個實體做爲參數該怎麼解決呢?咱們來看下面的代碼便知:

複製代碼

    $.ajax({
        type: "post",
        url: "http://localhost:27221/api/Charging/SaveData",
        data: { ID: "1", NAME: "Jim", CREATETIME: "1988-09-11" },
        success: function (data, status) {}
    });

        [HttpPost]
        public bool SaveData(TB_CHARGING oData)
        {
            return true;
        }

複製代碼

獲得結果

原理解釋:使用實體做爲參數的時候,前端直接傳遞普通json,後臺直接使用對應的類型去接收便可,不用FromBody。可是這裏須要注意的一點就是,這裏不能指定contentType爲appplication/json,不然,參數沒法傳遞到後臺。咱們來看看它默認的contentType是什麼:

 

爲了弄清楚緣由,博主查了下http的Content-Type的類型。看到以下說明:

  • application/x-www-form-urlencoded : <form encType=」」>中默認的encType,form表單數據被編碼爲key/value格式發送到服務器(表單默認的提交數據的格式);
  • application/json    : JSON數據格式

也就是說post請求默認是將表單裏面的數據的key/value形式發送到服務,而咱們的服務器只須要有對應的key/value屬性值的對象就能夠接收到。而若是使用application/json,則表示將前端的數據以序列化過的json傳遞到後端,後端要把它變成實體對象,還須要一個反序列化的過程。按照這個邏輯,那咱們若是指定contentType爲application/json,而後傳遞序列化過的對象應該也是能夠的啊。博主好奇心重,仍是打算一試到底,因而就有了下面的代碼:

複製代碼

var postdata = { ID: "1", NAME: "Jim", CREATETIME: "1988-09-11" };
    $.ajax({
        type: "post",
        url: "http://localhost:27221/api/Charging/SaveData",
        contentType: 'application/json',
        data: JSON.stringify(postdata),
        success: function (data, status) {}
    });
        [HttpPost]
        public bool SaveData(TB_CHARGING lstCharging)
        {
            return true;
        }

複製代碼

獲得結果:

嘗試成功,也就是說,兩種寫法都是可行的。若是你指定了contentType爲application/json,則必需要傳遞序列化過的對象;若是使用post請求的默認參數類型,則前端直接傳遞json類型的對象便可。 

(2)實體和基礎類型一塊兒做爲參數傳遞

有些時候,咱們須要將基礎類型和實體一塊兒傳遞到後臺,這個時候,咱們神奇的dynamic又派上用場了。

複製代碼

var postdata = { ID: "1", NAME: "Jim", CREATETIME: "1988-09-11" };
    $.ajax({
        type: "post",
        url: "http://localhost:27221/api/Charging/SaveData",
        contentType: 'application/json',
        data: JSON.stringify({ NAME:"Lilei", Charging:postdata }),
        success: function (data, status) {}
    });

        [HttpPost]
        public object SaveData(dynamic obj)
        {
            var strName = Convert.ToString(obj.NAME);
            var oCharging = Newtonsoft.Json.JsonConvert.DeserializeObject<TB_CHARGING>(Convert.ToString(obj.Charging));
            return strName;
        }

複製代碼

獲得結果:

三、數組做爲參數

(1)基礎類型數組

複製代碼

var arr = ["1", "2", "3", "4"];
    $.ajax({
        type: "post",
        url: "http://localhost:27221/api/Charging/SaveData",
        contentType: 'application/json',
        data: JSON.stringify(arr),
        success: function (data, status) { }
    });

        [HttpPost]
        public bool SaveData(string[] ids)
        {
            return true;
        }

複製代碼

獲得結果:

(2)實體集合

複製代碼

var arr = [
        { ID: "1", NAME: "Jim", CREATETIME: "1988-09-11" },
        { ID: "2", NAME: "Lilei", CREATETIME: "1990-12-11" },
        { ID: "3", NAME: "Lucy", CREATETIME: "1986-01-10" }
    ];
    $.ajax({
        type: "post",
        url: "http://localhost:27221/api/Charging/SaveData",
        contentType: 'application/json',
        data: JSON.stringify(arr),
        success: function (data, status) {}
    });

        [HttpPost]
        public bool SaveData(List<TB_CHARGING> lstCharging)
        {
            return true;
        }

複製代碼

獲得結果:

四、後臺發送請求參數的傳遞

上面寫了那麼多,都是經過前端的ajax請求去作的,咱們知道,若是調用方不是web項目,好比Android客戶端,可能須要從後臺發送http請求來調用咱們的接口方法,若是咱們經過後臺去發送請求是否也是可行的呢?咱們以實體對象做爲參數來傳遞寫寫代碼試一把。

複製代碼

 public void TestReques()
    {
         //請求路徑
            string url = "http://localhost:27221/api/Charging/SaveData";

            //定義request並設置request的路徑
            WebRequest request = WebRequest.Create(url);
            request.Method = "post";

            //初始化request參數
            string postData = "{ ID: \"1\", NAME: \"Jim\", CREATETIME: \"1988-09-11\" }";

            //設置參數的編碼格式,解決中文亂碼
            byte[] byteArray = Encoding.UTF8.GetBytes(postData);

            //設置request的MIME類型及內容長度
            request.ContentType = "application/json";
            request.ContentLength = byteArray.Length;

            //打開request字符流
            Stream dataStream = request.GetRequestStream();
            dataStream.Write(byteArray, 0, byteArray.Length);
            dataStream.Close();

            //定義response爲前面的request響應
            WebResponse response = request.GetResponse();

            //獲取相應的狀態代碼
            Console.WriteLine(((HttpWebResponse)response).StatusDescription);

            //定義response字符流
            dataStream = response.GetResponseStream();
            StreamReader reader = new StreamReader(dataStream);
            string responseFromServer = reader.ReadToEnd();//讀取全部
            Console.WriteLine(responseFromServer);
    }

複製代碼

當代碼運行到request.GetResponse()這一句的時候,API裏面進入斷點

嘗試成功。

3、put請求

WebApi裏面put請求通常用於對象的更新。它和用法和post請求基本相同。一樣支持[FromBody],一樣可使用dynamic。

一、基礎類型參數

複製代碼

    $.ajax({
        type: "put",
        url: "http://localhost:27221/api/Charging/Update",
        contentType: 'application/json',
        data: JSON.stringify({ ID: "1" }),
        success: function (data, status) {}
    });

        [HttpPut]
        public bool Update(dynamic obj )
        {
            return true;
        }

複製代碼

二、實體做爲參數

和post請求相同。

三、數組做爲參數

和post請求相同。

4、delete請求

顧名思義,delete請求確定是用於刪除操做的。參數傳遞機制和post也是基本相同。下面簡單給出一個例子,其餘狀況參考post請求。

複製代碼

var arr = [
        { ID: "1", NAME: "Jim", CREATETIME: "1988-09-11" },
        { ID: "2", NAME: "Lilei", CREATETIME: "1990-12-11" },
        { ID: "3", NAME: "Lucy", CREATETIME: "1986-01-10" }
    ];
    $.ajax({
        type: "delete",
        url: "http://localhost:27221/api/Charging/OptDelete",
        contentType: 'application/json',
        data: JSON.stringify(arr),
        success: function (data, status) {}
    });

        [HttpDelete]
        public bool OptDelete(List<TB_CHARGING> lstChargin)
        {
            return true;
        }

複製代碼

 

博文的一點評論:

dynamic雖然很巧妙地解決了從請求body中獲取參數。可是這樣不利於生成api文檔。
ps:通常都是用pagehelp等工具,自動讀取元數據,生成api文檔的。
若是用dynamic的話,生成的文檔就只有一個dynamic類型的參數,這樣api調用者就沒法明確api的參數了。

還有接收參數定義爲dynamic類型的話,後續維護或升級太麻煩。

 

若是是post操做。文中介紹了兩種傳遞實體參數的方法
第一種:

1

data: { ID: "1", NAME: "Jim", CREATETIME: "1988-09-11" }


不須要指定contentType。
第二種:

1

data: "{\"SoldToParty\":\"fdsfds\",\"SaleOrg\":\"fdsfds\",\"Channel\":\"ffffff\",\"Division\":\"dfdfsdsfd\"}"

須要指定contentType:"application/json"。兩種方式後臺均可以獲得實體。不知道你的Json字符串是怎麼獲得的,是拼的字符串?建議使用JSON.stringify( { ID: "1", NAME: "Jim", CREATETIME: "1988-09-11" })這種方式獲得json字符串。

相關文章
相關標籤/搜索