WebApi系列文章html
【02】聊聊WebApi體系結構json
【09】詳解系列化和模型綁定post
閱讀目錄
1.1 [FromBody]單個參數傳遞
5 小結
一 概述
通常地,咱們在研究一個問題時,常規的思路是爲該問題建模;咱們在研究類似問題時,常規思路是找出這些問題的共性和異性。基於該思路,咱們如何研究WebApi參數傳遞問題呢?
首先,從參數自己來講,種類較爲多(如int,double,float,string,array,Object等),且有些類型較爲複雜(如值類型和引用類型的機制等);
其次,從基於WebApi的Http請求方法來講,種類多且不盡相同(如Get,post,Delete,put,head等),在上一篇文章 :【WebApi系列】淺談HTTP在WebApi開發中的運用 中,咱們簡要描述了Http請求的20個方法;
..........
如此複雜且不盡相同,關於WebApi參數傳遞,咱們該選擇什麼做爲切入點來研究呢?基於咱們上面提到的研究思路,咱們想到了.NET Framework框架,那麼,咱們來看看基於.NET Framework框架的的WebApi
模板是怎樣的呢?
請按圖中步驟操做
咱們來看看Values控制器是怎樣的
1 public class ValuesController : ApiController 2 { 3 // GET api/values 4 public IEnumerable<string> Get() 5 { 6 return new string[] { "value1", "value2" }; 7 } 8 9 // GET api/values/5 10 public string Get(int id) 11 { 12 return "value"; 13 } 14 15 // POST api/values 16 public void Post([FromBody]string value) 17 { 18 } 19 20 // PUT api/values/5 21 public void Put(int id, [FromBody]string value) 22 { 23 } 24 25 // DELETE api/values/5 26 public void Delete(int id) 27 { 28 } 29 }
從Values控制器,咱們不可貴出以下幾個結論:
(1)WebApi常規方法爲四個:Get,Post,Put和Delete;
(2)四種方法的參數可歸結爲兩大類:url傳遞(Request-url)和Body(Request-body)傳遞;
(3)基於(2),咱們將四種方法的參數傳遞歸爲兩大類,而這兩大類又集中在Get和Post中體現了(Put是Get和Post的組合,Delete與Get相似);
其實,分析到如今,咱們很容易找獲得了研究WebApi參數傳遞的切入點?研究Get和Post方法參數傳遞便可。是的,沒錯,咱們本篇文章就是基於Get和Post方法的參數傳遞,前者對應Request-url,後者對應Reqeust-Body。
二 Get
1 基礎數據類型
1.1 方法只含一個形參(參數傳得進去)
ajax
$(document).ready(function () { $("#FindProdcutDetail").click(function () { $.ajax({ type: "Get", //url: "/api/Default/GetProductDetails?ProductCode=JX80869" url: "/api/Default/GetProductDetails", data: { "ProductCode":"JX80869"} }) }) })
Result
總結
(1)當Get方法形參爲一個且爲基本數據類型時,Get方法能接受外部傳遞的值
(2)Get傳值的本質是經過url字符串拼接,如上兩兩種url形式的傳遞的結果都是同樣
url形式1
url: "/api/Default/GetProductDetails?ProductCode=JX80869"
url形式2
url: "/api/Default/GetProductDetails",
data: { "ProductCode":"JX80869"}
咱們用Goole Chrome來看看結果,發現url形式1和url形式2均一致
(3)Get傳遞參數本質是url字符串拼接,Request-Head頭部傳遞,Request-Body中不能傳遞(這是與Post方法的本質區別),咱們舉兩個例子
例子1:咱們將形參添加[FromBody]屬性後,值傳遞不進去
例子2:咱們用PostMan來測試,發現PostMan中,Get方法參數Body爲灰色,是不能選中的
1.2 方法含有多個形參(參數傳得進去)
$(document).ready(function () { $("#FindProdcutDetail").click(function () { $.ajax({ type: "Get", url: "/api/Default/GetProductDetails", data: { "ProductCode": "JX80869","ProductName":"YaGao"} }) }) })
result
2 實體對象類型(參數傳不進去)
model
1 public class ProductDetail 2 { 3 //產品編碼 4 [Required] 5 public string ProductCode { get; set; } 6 //產品名稱 7 [Required] 8 public string ProductName { get; set; } 9 //產品價格 10 [Required] 11 public double ProductPrice{ get; set; } 12 }
ajax
$(document).ready(function () { var productDetail = { "ProductName": "YaGao", "ProductCode": "JX80869", "ProductPrice": 40.5}; $("#FindProdcutDetail").click(function () { $.ajax({ type: "Get", url: "/api/Default/ProductDetails", data: productDetail }) }) })
result:
分析
3 實體對象和基礎數據類型混合(實體傳不進去,基礎數據能傳遞進去)
ajax
1 $(document).ready(function () { 2 $("#FindProdcutDetail").click(function () { 3 $.ajax({ 4 type: "Get", 5 url: "/api/Default/GetProductDetails", 6 data: { "_productDetail": "ObjectEntity","ProductName":"YaGao"} 7 }) 8 }) 9 })
result
4 最小知足原則(參數傳得進去)
所謂「最小知足原則」,指外部參數必須至少知足被調用方法的形參(形參個數,形參類型和形參名字),換句話說,被調用方法具備的形參,外部參數必須傳遞進來,被調用方法沒有
的形參,外部參數傳遞與否均可以,不然將會產生狀態碼404錯誤,用數學集合的思路來理解的話,被調用方法的形參至關於外部參數的子集。以下例子,咱們舉一個真子集的例子,
即外部傳遞參數的個數大於被調方法的的形參個數。
Ajax
$(document).ready(function () { $("#FindProdcutDetail").click(function () { $.ajax({ type: "Get", url: "/api/Default/GetProductDetails", data: {"ProductCode": "JX00034", "ProductName": "YaGao", "ProductPrice": 20.5, "PrudcutType": "Daily Necessities"} }) }) })
result
分析:主要緣由是路由規則,路由從url裏面取參數與aciton參數匹配,直到匹配知足爲止,具體詳細深刻內容,在【WebApi系列】路由章節分析。
5 url長度限制
url參數長度是有必定限制的,當超過必定長度,會報404錯誤
ajax
$(document).ready(function () { $("#FindProdcutDetail").click(function () { $.ajax({ type: "Get", url: "/api/Default/GetProductDetails", data: { "ProductCode": "JX00034xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" + "JX00034xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" + "JX00034xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" + "JX00034xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" + "JX00034xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" + "JX00034xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" + "JX00034xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" + "JX00034xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" + "JX00034xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" + "JX00034xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" + "JX00034xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" + "JX00034xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" + "JX00034xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" + "JX00034xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" + "JX00034xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" + "JX00034xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" + "JX00034xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" + "JX00034xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" + "JX00034xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" + "JX00034xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" + "JX00034xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" + "JX00034xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" + "JX00034xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" + "JX00034xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" + "JX00034xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" + "JX00034xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" } }) }) })
result
6 Get規範化
關於Get類型規範化,應注意兩點,避免沒必要要的錯誤或異常:(1)方法的命名儘可能採用:「Get+方法名」的形式 (2)在每一個方法上加上特性[HttpGet]。
例子:咱們去掉[HttpGet]特性和方法前的Get,看看狀況什麼怎樣的
ajax
$(document).ready(function () { $("#FindProdcutDetail").click(function () { $.ajax({ type: "Get", url: "/api/Default/ProductDetails", data: {"ProductCode": "JX00034 "} }) }) })
Controller
1 public class DefaultController : ApiController 2 { 3 4 //[HttpGet] 5 public string ProductDetails(string ProductCode) 6 { 7 return "values"; 8 } 9 }
Result
7 關於實體做爲參數傳遞的拓展
7.1 藉助[FromUri]特性傳遞實體
ajax
$(document).ready(function () { var GetEntityParam = { "ProductName": "YaGao", "ProductCode": "JX80869", "ProductPrice": 40.5}; $("#FindProdcutDetail").click(function () { $.ajax({ type: "Get", url: "/api/Default/ProductDetails", data: GetEntityParam }) }) })
result
7.2 系列化與反系列化傳遞實體
ajax
$(document).ready(function () { $("#FindProdcutDetail").click(function () { $.ajax({ type: "Get", url: "/api/Default/ProductDetails", data: { "productDetail": JSON.stringify({ "ProductName": "YaGao", "ProductCode": "JX80869", "ProductPrice": 40.5 }) } }) }) })
result
8 小結
(1)Get參數傳遞的本質是url字符串拼接;
(2)url字符串長度受限制;
(3)Get參數傳遞在Http請求頭部傳遞,而不支持Request-Body傳遞;
(4)Get類型的方法支持參數爲基本類型,不支持實體類型;
(5)Get類型的方法命名,應儘可能採用「Get+方法名」的命名方式,且習慣性地在方法前加上[HttpGet特性];
(6)實參與形參的匹配,遵循路由規則;
(7)Get對應DB的Select操做,從這一點來理解,就知道爲何Http不支持實體對象傳遞的合理性了,由於通常狀況,咱們都是經過簡單的字段查詢信息(對應基本類型),
如ID號,用戶名等,而不會經過一個實體查詢數據;
三 Post
1 基本數據類型傳遞
1.1 [FromBody]單個參數傳遞
ajax
result
1.2 dynamic單個參數傳遞
ajax
$(document).ready(function () { $("#FindProdcutDetail").click(function () { $.ajax({ type: "Post", contentType: 'application/json', url: "/api/Default/PostParamToProducts", data: JSON.stringify({"ProductCode":"JX00039"}) }) }) })
result
Googel Chrome查看
2 實體做爲參數傳遞
ajax
$(document).ready(function () { $("#FindProdcutDetail").click(function () { $.ajax({ type: "Post", url: "/api/Default/PostParamToProducts", data: { "ProductCode": "JX00036","ProductName":"YaGao","ProductPrice":20.5} }) }) })
result
咱們用Googel Chrome看看
3 實體集合做爲參數傳遞
ajax
$(document).ready(function () { var list_ProductDetail = [ { "ProductCode": "JX00031", "ProductName": "ToothPaste", "ProductPrice": "20.5" }, { "ProductCode": "JX00032", "ProductName": "ToothBrush ", "ProductPrice": "18.9" }, { "ProductCode": "JX00033", "ProductName": "Pen", "ProductPrice": "199.9" }, { "ProductCode": "JX00034", "ProductName": "computer", "ProductPrice": "15000.5" } ] $("#FindProdcutDetail").click(function () { $.ajax({ type: "Post", contentType: 'application/json', url: "/api/Default/PostParamToProducts", data: JSON.stringify(list_ProductDetail) }) }) })
result
Google Chrome 查看
4 數組做爲參數傳遞
ajax
$(document).ready(function () { var arr = ["a", "b", "c", "d"]; $("#FindProdcutDetail").click(function () { $.ajax({ type: "Post", contentType: 'application/json', url: "/api/Default/PostParamToProducts", data: JSON.stringify(arr) }) }) })
Result
咱們用Google Chrome看看
5 小結
(1)Post參數傳遞本事是在Request-Body內傳遞,而Get參數傳遞本質是url拼接;
(2)Post參數傳遞不是key/value形式,而Get參數是key/value形式;
(3)Post傳遞參數時,不管是單個參數仍是對象,均藉助[FromBody]特性(固然,某些狀況去掉[FromBody]特性也可把值傳遞進去,但未了規範化,儘可能加上該特性);
(4)Post沒長度限制,而Get有長度限制(通常爲1024b);
(5)Post相對Get,較安全;
(6)Post操做至關於DB的Insert操做;
四 總結
1.雖然HTTP請求方法有20多種,經常使用的大體爲4種,即Get,Post,Put,Delete(固然,像Trace,Head等也經常使用);
2.Get,Post,Put,Delete分別對應DB的Select,Insert,Update和Delete操做;
3.WebApi參數類型,大體分爲基本數據類類型和對象數據類型(固然你也能夠理解爲抽象數據類型);
4.研究WebApi參數傳遞,只需研究Get和Post便可,由於其餘http方法參數傳遞基本都是有這兩種組合而成(如Put有Get和Post組合而成),或者類似(如Delete與Get類似);
5.對於控制器方法,儘可能參照規範格式寫,如在相應控制器方法上加上對應的htt請求(Get對應[HttpGet],Post對應[HttpPost]),方法名儘可能採用「Http請類型+方法名」格式(如Get請求,建議採用Get+MethodName;Post請求對應Post+MethodName);
6.WebApi參數請求,大體分爲兩大類型,即Request-url和Request-body;
7.文中咱們還簡要分析了Get和Post區別;
8.關於如何設計一個良好的接口,在文章中,咱們觸及了一下,但未研究,會在後續的文章中單獨分析;
五 服務區
有喜歡的朋友,能夠看一下,不喜歡的的朋友,勿噴,謝謝!!
六 版權區