国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 學院 > 開發設計 > 正文

WebApi接口傳參不再困惑:傳參詳解

2019-11-08 02:06:25
字體:
來源:轉載
供稿:網友

一、get請求

對于取數據,我們使用最多的應該就是get請求了吧。下面通過幾個示例看看我們的get請求參數傳遞。

1、基礎類型參數

[csharp] view plain copy[HttpGet]  public string GetAllChargingData(int id, string name)  {      return "ChargingData" + id;  }  [javascript] view plain copy$.Ajax({          type: "get",          url: "http://localhost:27221/api/Charging/GetAllChargingData",          data: { id: 1, name: "Jim", bir: "1988-09-11"},          success: function (data, status) {              if (status == "success") {                  $("#div_test").html(data);              }          }      });   這是get請求最基礎的參數傳遞方式,沒什么特別好說的。

2、實體作為參數

如果我們在get請求時想將實體對象做參數直接傳遞到后臺,是否可行呢?我們來看看。

[csharp] view plain copypublic class TB_CHARGING      {          /// <summary>          /// 主鍵Id          /// </summary>          public string ID { get; set; }            /// <summary>          /// 充電設備名稱          /// </summary>          public string NAME { get; set; }            /// <summary>          /// 充電設備描述          /// </summary>          public string DES { get; set; }            /// <summary>          /// 創建時間          /// </summary>          public DateTime CREATETIME { get; set; }      }  [csharp] view plain copy[HttpGet]  public string GetByModel(TB_CHARGING oData)  {       return "ChargingData" + oData.ID;  }  [Javascript] view plain copy$.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);              }          }      });  

測試結果: 在get請求時,我們直接將json對象當做實體傳遞后臺,后臺是接收不到的。這是為什么呢?我們來看看對應的http請求

[html] view plain copy<img src="http://images2015.cnblogs.com/blog/459756/201603/459756-20160331104121410-719598113.png" alt="" />  

原來,get請求的時候,默認是將參數全部放到了url里面直接以string的形式傳遞的,后臺自然接不到了。

原因分析:還記得有面試題問過get和post請求的區別嗎?其中有一個區別就是get請求的數據會附在URL之后(就是把數據放置在HTTP協議頭中),而post請求則是放在http協議包的包體中。

根據園友們的提議,Get請求的時候可以在參數里面加上[FromUri]即可直接得到對象。還是貼上代碼:

[javascript] view plain copyvar postdata = { ID: "1", NAME: "Jim", CREATETIME: "1988-09-11" };      $.ajax({          type: "get",          url: "http://localhost:27221/api/Charging/GetAllChargingData",          data: postdata,          success: function (data, status) { }      });  [csharp] view plain copy[HttpGet]          public string GetAllChargingData([FromUri]TB_CHARGING obj)          {              return "ChargingData" + obj.ID;          }  得到結果:

如果你不想使用[FromUri]這些在參數里面加特性的這種“怪異”寫法,也可以采用先序列化,再在后臺反序列的方式。

[javascript] view plain copy$.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);              }          }      });  [csharp] view plain copy[HttpGet]          public string GetByModel(string strQuery)          {              TB_CHARGING oData = Newtonsoft.Json.JsonConvert.DeserializeObject<TB_CHARGING>(strQuery);              return "ChargingData" + oData.ID;          }  

這樣在后臺得到我們序列化過的對象,再通過反序列化就能得到對象。

在url里面我們可以看到它自動給對象加了一個編碼:

3、數組作為參數

一般get請求不建議將數組作為參數,因為我們知道get請求傳遞參數的大小是有限制的,最大1024字節,數組里面內容較多時,將其作為參數傳遞可能會發生參數超限丟失的情況。

4、“怪異”的get請求

為什么會說get請求“怪異”呢?我們先來看看下面的兩種寫法對比。

(1)WebApi的方法名稱以get開頭

[javascript] view plain copy$.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);              }          }      });  [csharp] view plain copy[HttpGet]          public string GetByModel(string strQuery)          {              TB_CHARGING oData = Newtonsoft.Json.JsonConvert.DeserializeObject<TB_CHARGING>(strQuery);              return "ChargingData" + oData.ID;          }  這是標準寫法,后臺加[HttpGet],參數正常得到:

為了對比,我將[HttpGet]去掉,然后再調用

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

貌似沒有任何問題!有人就想,那是否所有的get請求都可以省略掉[HttpGet]這個標注呢。我們試試便知。

(2)WebApi的方法名稱不以get開頭

我們把之前的方法名由GetByModel改成FindByModel,這個再正常不過了,很多人查詢就不想用Get開頭,還有直接用Query開頭的。這個有什么關系嗎?有沒有關系,我們以事實說話。

[javascript] view plain copy$.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);              }          }      });  [csharp] view plain copy[HttpGet]          public string FindByModel(string strQuery)          {              TB_CHARGING oData = Newtonsoft.Json.JsonConvert.DeserializeObject<TB_CHARGING>(strQuery);              return "ChargingData" + oData.ID;          }  

貌似又可行,沒有任何問題啊。根據上面的推論,我們去掉[HttpGet]也是可行的,好,我們注釋掉[HttpGet],運行起來試試。

結果是不進斷點,有些人不信,我們在瀏覽器里面看看http請求:

呵呵,這就奇怪了,就改了個方法名,至于這樣么?還真至于!

博主的理解是:方法名以Get開頭,WebApi會自動默認這個請求就是get請求,而如果你以其他名稱開頭而又不標注方法的請求方式,那么這個時候服務器雖然找到了這個方法,但是由于請求方式不確定,所以直接返回給你405——方法不被允許的錯誤。

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

這也就是為什么很多人在園子里面問道為什么方法名不加[HttpGet]就調用不到的原因!

二、post請求

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

1、基礎類型參數

 post請求的基礎類型的參數和get請求有點不一樣,我們知道get請求的參數是通過url來傳遞的,而post請求則是通過http的請求體中傳過來的,WebApi的post請求也需要從http的請求體里面去取參數。

(1)錯誤的寫法

[javascript] view plain copy$.ajax({          type: "post",          url: "http://localhost:27221/api/Charging/SaveData",          data: { NAME: "Jim" },          success: function (data, status) {              if (status == "success") {                  $("#div_test").html(data);              }          }      });  [csharp] view plain copy[HttpPost]          public bool SaveData(string NAME)          {              return true;          }  這是一種看上去非常正確的寫法,可是實際情況是:

(2)正確的用法

[javascript] view plain copy$.ajax({         type: "post",         url: "http://localhost:27221/api/Charging/SaveData",         data: { "": "Jim" },         success: function (data, status) {}     });  [csharp] view plain copy[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)錯誤寫法

[javascript] view plain copy$.ajax({          type: "post",          url: "http://localhost:27221/api/Charging/SaveData",          data: { "": "Jim","":"備注" },          success: function (data, status) {}      });  [csharp] view plain copy[HttpPost]          public bool SaveData([FromBody]string NAME, [FromBody] string DES)          {              return true;          }  得到結果

這說明我們沒辦法通過多個[FromBody]里面取值,此法失敗。

(2)正確用法

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

[javascript] view plain copy$.ajax({          type: "post",          url: "http://localhost:27221/api/Charging/SaveData",          contentType: 'application/json',          data: JSON.stringify({ NAME: "Jim",DES:"備注" }),          success: function (data, status) {}      });  [csharp] view plain copy[HttpPost]          public object SaveData(dynamic obj)          {              var strName = Convert.ToString(obj.NAME);              return strName;          }  

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

(3)推薦用法

通過上文post請求基礎類型參數的傳遞,我們了解到了dynamic的方便之處,為了避免[FromBody]這個累贅和{"":"value"}這種"無厘頭"的寫法。博主推薦所有基礎類型使用dynamic來傳遞,方便解決了基礎類型一個或多個參數的傳遞,示例如上文。如果園友們有更好的辦法,歡迎討論。

三、put請求

WebApi里面put請求一般用于對象的更新。它和用法和post請求基本相同。同樣支持[FromBody],同樣可以使用dynamic。

1、基礎類型參數

[javascript] view plain copy$.ajax({          type: "put",          url: "http://localhost:27221/api/Charging/Update",          contentType: 'application/json',          data: JSON.stringify({ ID: "1" }),          success: function (data, status) {}      });  [csharp] view plain copy[HttpPut]          public bool Update(dynamic obj )          {              return true;          }  

2、實體作為參數

和post請求相同。

3、數組作為參數

和post請求相同。

四、delete請求

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

[javascript] view plain copyvar 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) {}      });  

 

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

五、總結

以上比較詳細的總結了WebApi各種請求的各種參數傳遞。每種情況都是博主實際代碼測試過的,內容不難,但如果剛接觸這么些東西還是需要一點時間去熟悉的,在此做個總結,希望能幫到剛剛接觸WebApi的園友們。如果本文能幫到你,不妨推薦下,您的推薦是博主繼續總結的動力!

原文地址:http://www.cnblogs.com/landeanfen/p/5337072.html
發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 尖扎县| 八宿县| 襄樊市| 西乌| 宝山区| 高陵县| 青冈县| 什邡市| 南投县| 太保市| 余庆县| 宜宾县| 乐陵市| 平凉市| 营山县| 嘉荫县| 股票| 犍为县| 普宁市| 鄂托克旗| 福建省| 色达县| 乡宁县| 荣成市| 车险| 乌苏市| 赤峰市| 三明市| 嘉兴市| 乌拉特前旗| 特克斯县| 策勒县| 贵州省| 新蔡县| 青浦区| 望城县| 贺州市| 大竹县| 囊谦县| 安西县| 遂溪县|