您好,登錄后才能下訂單哦!
這期內(nèi)容當(dāng)中小編將會(huì)給大家?guī)?lái)有關(guān)使用C#怎么對(duì)WebApi 接口進(jìn)行傳參,文章內(nèi)容豐富且以專(zhuān)業(yè)的角度為大家分析和敘述,閱讀完這篇文章希望大家可以有所收獲。
一、get請(qǐng)求
對(duì)于取數(shù)據(jù),我們使用最多的應(yīng)該就是get請(qǐng)求了吧。下面通過(guò)幾個(gè)示例看看我們的get請(qǐng)求參數(shù)傳遞。
1、基礎(chǔ)類(lèi)型參數(shù)
[HttpGet] public string GetAllChargingData(int id, string name) { return "ChargingData" + id; }
$.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); } } });
參數(shù)截圖效果
這是get請(qǐng)求最基礎(chǔ)的參數(shù)傳遞方式,沒(méi)什么特別好說(shuō)的。
2、實(shí)體作為參數(shù)
如果我們?cè)趃et請(qǐng)求時(shí)想將實(shí)體對(duì)象做參數(shù)直接傳遞到后臺(tái),是否可行呢?我們來(lái)看看。
public class TB_CHARGING { /// <summary> /// 主鍵Id /// </summary> public string ID { get; set; } /// <summary> /// 充電設(shè)備名稱(chēng) /// </summary> public string NAME { get; set; } /// <summary> /// 充電設(shè)備描述 /// </summary> public string DES { get; set; } /// <summary> /// 創(chuàng)建時(shí)間 /// </summary> public DateTime CREATETIME { get; set; } }
[HttpGet] public string GetByModel(TB_CHARGING oData) { return "ChargingData" + oData.ID; }
$.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); } } });
測(cè)試結(jié)果
由上圖可知,在get請(qǐng)求時(shí),我們直接將json對(duì)象當(dāng)做實(shí)體傳遞后臺(tái),后臺(tái)是接收不到的。這是為什么呢?我們來(lái)看看對(duì)應(yīng)的http請(qǐng)求
原來(lái),get請(qǐng)求的時(shí)候,默認(rèn)是將參數(shù)全部放到了url里面直接以string的形式傳遞的,后臺(tái)自然接不到了。
原因分析:還記得有面試題問(wèn)過(guò)get和post請(qǐng)求的區(qū)別嗎?其中有一個(gè)區(qū)別就是get請(qǐng)求的數(shù)據(jù)會(huì)附在URL之后(就是把數(shù)據(jù)放置在HTTP協(xié)議頭中),而post請(qǐng)求則是放在http協(xié)議包的包體中。
根據(jù)園友們的提議,Get請(qǐng)求的時(shí)候可以在參數(shù)里面加上[FromUri]即可直接得到對(duì)象。還是貼上代碼:
var 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) { } });
[HttpGet] public string GetAllChargingData([FromUri]TB_CHARGING obj) { return "ChargingData" + obj.ID; }
得到結(jié)果:
如果你不想使用[FromUri]這些在參數(shù)里面加特性的這種“怪異”寫(xiě)法,也可以采用先序列化,再在后臺(tái)反序列的方式。
$.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; }
這樣在后臺(tái)得到我們序列化過(guò)的對(duì)象,再通過(guò)反序列化就能得到對(duì)象。
在url里面我們可以看到它自動(dòng)給對(duì)象加了一個(gè)編碼:
至于還有園友們提到http://www.asp.net/web-api/overview/formats-and-model-binding/parameter-binding-in-aspnet-web-api的model binder這種方式,博主看了下,覺(jué)得略復(fù)雜。有興趣的也可以試試。至于用哪一種方式傳遞對(duì)象,園友們可以自行選擇。
3、數(shù)組作為參數(shù)
一般get請(qǐng)求不建議將數(shù)組作為參數(shù),因?yàn)槲覀冎纆et請(qǐng)求傳遞參數(shù)的大小是有限制的,最大1024字節(jié),數(shù)組里面內(nèi)容較多時(shí),將其作為參數(shù)傳遞可能會(huì)發(fā)生參數(shù)超限丟失的情況。
4、“怪異”的get請(qǐng)求
為什么會(huì)說(shuō)get請(qǐng)求“怪異”呢?我們先來(lái)看看下面的兩種寫(xiě)法對(duì)比。
(1)WebApi的方法名稱(chēng)以get開(kāi)頭
$.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; }
這是標(biāo)準(zhǔn)寫(xiě)法,后臺(tái)加[HttpGet],參數(shù)正常得到:
為了對(duì)比,我將[HttpGet]去掉,然后再調(diào)用
//[HttpGet] public string GetByModel(string strQuery) { TB_CHARGING oData = Newtonsoft.Json.JsonConvert.DeserializeObject<TB_CHARGING>(strQuery); return "ChargingData" + oData.ID; }
貌似沒(méi)有任何問(wèn)題!有人就想,那是否所有的get請(qǐng)求都可以省略掉[HttpGet]這個(gè)標(biāo)注呢。我們?cè)囋嚤阒?/p>
(2)WebApi的方法名稱(chēng)不以get開(kāi)頭
我們把之前的方法名由GetByModel改成FindByModel,這個(gè)再正常不過(guò)了,很多人查詢(xún)就不想用Get開(kāi)頭,還有直接用Query開(kāi)頭的。這個(gè)有什么關(guān)系嗎?有沒(méi)有關(guān)系,我們以事實(shí)說(shuō)話(huà)。
$.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; }
貌似又可行,沒(méi)有任何問(wèn)題啊。根據(jù)上面的推論,我們?nèi)サ鬧HttpGet]也是可行的,好,我們注釋掉[HttpGet],運(yùn)行起來(lái)試試。
結(jié)果是不進(jìn)斷點(diǎn),有些人不信,我們?cè)跒g覽器里面看看http請(qǐng)求:
呵呵,這就奇怪了,就改了個(gè)方法名,至于這樣么?還真至于!
博主的理解是:方法名以Get開(kāi)頭,WebApi會(huì)自動(dòng)默認(rèn)這個(gè)請(qǐng)求就是get請(qǐng)求,而如果你以其他名稱(chēng)開(kāi)頭而又不標(biāo)注方法的請(qǐng)求方式,那么這個(gè)時(shí)候服務(wù)器雖然找到了這個(gè)方法,但是由于請(qǐng)求方式不確定,所以直接返回給你405——方法不被允許的錯(cuò)誤。
最后結(jié)論:所有的WebApi方法最好是加上請(qǐng)求的方式([HttpGet]/[HttpPost]/[HttpPut]/[HttpDelete]),不要偷懶,這樣既能防止類(lèi)似的錯(cuò)誤,也有利于方法的維護(hù),別人一看就知道這個(gè)方法是什么請(qǐng)求。
這也就是為什么很多人在園子里面問(wèn)道為什么方法名不加[HttpGet]就調(diào)用不到的原因!
二、post請(qǐng)求
在WebApi的RESETful風(fēng)格里面,API服務(wù)的增刪改查,分別對(duì)應(yīng)著http的post/delete/put/get請(qǐng)求。我們下面就來(lái)說(shuō)說(shuō)post請(qǐng)求參數(shù)的傳遞方式。
1、基礎(chǔ)類(lèi)型參數(shù)
post請(qǐng)求的基礎(chǔ)類(lèi)型的參數(shù)和get請(qǐng)求有點(diǎn)不一樣,我們知道get請(qǐng)求的參數(shù)是通過(guò)url來(lái)傳遞的,而post請(qǐng)求則是通過(guò)http的請(qǐng)求體中傳過(guò)來(lái)的,WebApi的post請(qǐng)求也需要從http的請(qǐng)求體里面去取參數(shù)。
(1)錯(cuò)誤的寫(xiě)法
$.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; }
這是一種看上去非常正確的寫(xiě)法,可是實(shí)際情況是:
(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; }
這是一種另許多人頭痛的寫(xiě)法,但是沒(méi)辦法,這樣確實(shí)能得到我們的結(jié)果:
我們一般的通過(guò)url取參數(shù)的機(jī)制是鍵值對(duì),即某一個(gè)key等于某一個(gè)value,而這里的FromBody和我們一般通過(guò)url取參數(shù)的機(jī)制則不同,它的機(jī)制是=value,沒(méi)有key的概念,并且如果你寫(xiě)了key(比如你的ajax參數(shù)寫(xiě)的{NAME:"Jim"}),后臺(tái)反而得到的NAME等于null。不信你可以試試。
上面講的都是傳遞一個(gè)基礎(chǔ)類(lèi)型參數(shù)的情況,那么如果我們需要傳遞多個(gè)基礎(chǔ)類(lèi)型呢?按照上面的推論,是否可以([FromBody]string NAME, [FromBody]string DES)這樣寫(xiě)呢。試試便知。
(1)錯(cuò)誤寫(xiě)法
$.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; }
得到結(jié)果
這說(shuō)明我們沒(méi)辦法通過(guò)多個(gè)[FromBody]里面取值,此法失敗。
(2)正確用法
既然上面的辦法行不通,那我們?nèi)绾蝹鬟f多個(gè)基礎(chǔ)類(lèi)型的數(shù)據(jù)呢?很多的解決辦法是新建一個(gè)類(lèi)去包含傳遞的參數(shù),博主覺(jué)得這樣不夠靈活,因?yàn)槿绻覀兦昂笈_(tái)每次傳遞多個(gè)參數(shù)的post請(qǐng)求都去新建一個(gè)類(lèi)的話(huà),我們系統(tǒng)到時(shí)候會(huì)有多少個(gè)這種參數(shù)類(lèi)?維護(hù)起來(lái)那是相當(dāng)?shù)穆闊┑囊患拢∷圆┲饔X(jué)得使用dynamic是一個(gè)很不錯(cuò)的選擇。我們來(lái)試試。
$.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; }
通過(guò)dynamic動(dòng)態(tài)類(lèi)型能順利得到多個(gè)參數(shù),省掉了[FromBody]這個(gè)累贅,并且ajax參數(shù)的傳遞不用使用"無(wú)厘頭"的{"":"value"}這種寫(xiě)法,有沒(méi)有一種小清新的感覺(jué)~~有一點(diǎn)需要注意的是這里在ajax的請(qǐng)求里面需要加上參數(shù)類(lèi)型為Json,即contentType: 'application/json',這個(gè)屬性。
(3)推薦用法
通過(guò)上文post請(qǐng)求基礎(chǔ)類(lèi)型參數(shù)的傳遞,我們了解到了dynamic的方便之處,為了避免[FromBody]這個(gè)累贅和{"":"value"}這種"無(wú)厘頭"的寫(xiě)法。博主推薦所有基礎(chǔ)類(lèi)型使用dynamic來(lái)傳遞,方便解決了基礎(chǔ)類(lèi)型一個(gè)或多個(gè)參數(shù)的傳遞,示例如上文。如果園友們有更好的辦法,歡迎討論。
2、實(shí)體作為參數(shù)
(1)單個(gè)實(shí)體作為參數(shù)
上面我們通過(guò)dynamic類(lèi)型解決了post請(qǐng)求基礎(chǔ)類(lèi)型數(shù)據(jù)的傳遞問(wèn)題,那么當(dāng)我們需要傳遞一個(gè)實(shí)體作為參數(shù)該怎么解決呢?我們來(lái)看下面的代碼便知:
$.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; }
得到結(jié)果
原理解釋?zhuān)菏褂脤?shí)體作為參數(shù)的時(shí)候,前端直接傳遞普通json,后臺(tái)直接使用對(duì)應(yīng)的類(lèi)型去接收即可,不用FromBody。但是這里需要注意的一點(diǎn)就是,這里不能指定contentType為appplication/json,否則,參數(shù)無(wú)法傳遞到后臺(tái)。我們來(lái)看看它默認(rèn)的contentType是什么:
為了弄清楚原因,博主查了下http的Content-Type的類(lèi)型??吹饺缦抡f(shuō)明:
application/x-www-form-urlencoded : <form encType=””>中默認(rèn)的encType,form表單數(shù)據(jù)被編碼為key/value格式發(fā)送到服務(wù)器(表單默認(rèn)的提交數(shù)據(jù)的格式);
application/json : JSON數(shù)據(jù)格式
也就是說(shuō)post請(qǐng)求默認(rèn)是將表單里面的數(shù)據(jù)的key/value形式發(fā)送到服務(wù),而我們的服務(wù)器只需要有對(duì)應(yīng)的key/value屬性值的對(duì)象就可以接收到。而如果使用application/json,則表示將前端的數(shù)據(jù)以序列化過(guò)的json傳遞到后端,后端要把它變成實(shí)體對(duì)象,還需要一個(gè)反序列化的過(guò)程。按照這個(gè)邏輯,那我們?nèi)绻付╟ontentType為application/json,然后傳遞序列化過(guò)的對(duì)象應(yīng)該也是可以的啊。博主好奇心重,還是打算一試到底,于是就有了下面的代碼:
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; }
得到結(jié)果:
嘗試成功,也就是說(shuō),兩種寫(xiě)法都是可行的。如果你指定了contentType為application/json,則必須要傳遞序列化過(guò)的對(duì)象;如果使用post請(qǐng)求的默認(rèn)參數(shù)類(lèi)型,則前端直接傳遞json類(lèi)型的對(duì)象即可。
(2)實(shí)體和基礎(chǔ)類(lèi)型一起作為參數(shù)傳遞
有些時(shí)候,我們需要將基礎(chǔ)類(lèi)型和實(shí)體一起傳遞到后臺(tái),這個(gè)時(shí)候,我們神奇的dynamic又派上用場(chǎng)了。
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; }
得到結(jié)果:
原理也不用多說(shuō),同上。
3、數(shù)組作為參數(shù)
(1)基礎(chǔ)類(lèi)型數(shù)組
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; }
得到結(jié)果:
(2)實(shí)體集合
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; }
得到結(jié)果:
4、后臺(tái)發(fā)送請(qǐng)求參數(shù)的傳遞
上面寫(xiě)了那么多,都是通過(guò)前端的ajax請(qǐng)求去做的,我們知道,如果調(diào)用方不是web項(xiàng)目,比如Android客戶(hù)端,可能需要從后臺(tái)發(fā)送http請(qǐng)求來(lái)調(diào)用我們的接口方法,如果我們通過(guò)后臺(tái)去發(fā)送請(qǐng)求是否也是可行的呢?我們以實(shí)體對(duì)象作為參數(shù)來(lái)傳遞寫(xiě)寫(xiě)代碼試一把。
public void TestReques() { //請(qǐng)求路徑 string url = "http://localhost:27221/api/Charging/SaveData"; //定義request并設(shè)置request的路徑 WebRequest request = WebRequest.Create(url); request.Method = "post"; //初始化request參數(shù) string postData = "{ ID: \"1\", NAME: \"Jim\", CREATETIME: \"1988-09-11\" }"; //設(shè)置參數(shù)的編碼格式,解決中文亂碼 byte[] byteArray = Encoding.UTF8.GetBytes(postData); //設(shè)置request的MIME類(lèi)型及內(nèi)容長(zhǎng)度 request.ContentType = "application/json"; request.ContentLength = byteArray.Length; //打開(kāi)request字符流 Stream dataStream = request.GetRequestStream(); dataStream.Write(byteArray, 0, byteArray.Length); dataStream.Close(); //定義response為前面的request響應(yīng) WebResponse response = request.GetResponse(); //獲取相應(yīng)的狀態(tài)代碼 Console.WriteLine(((HttpWebResponse)response).StatusDescription); //定義response字符流 dataStream = response.GetResponseStream(); StreamReader reader = new StreamReader(dataStream); string responseFromServer = reader.ReadToEnd();//讀取所有 Console.WriteLine(responseFromServer); }
當(dāng)代碼運(yùn)行到request.GetResponse()這一句的時(shí)候,API里面進(jìn)入斷點(diǎn)
嘗試成功。
三、put請(qǐng)求
WebApi里面put請(qǐng)求一般用于對(duì)象的更新。它和用法和post請(qǐng)求基本相同。同樣支持[FromBody],同樣可以使用dynamic。
1、基礎(chǔ)類(lèi)型參數(shù)
$.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; }
2、實(shí)體作為參數(shù)
和post請(qǐng)求相同。
3、數(shù)組作為參數(shù)
和post請(qǐng)求相同。
四、delete請(qǐng)求
顧名思義,delete請(qǐng)求肯定是用于刪除操作的。參數(shù)傳遞機(jī)制和post也是基本相同。下面簡(jiǎn)單給出一個(gè)例子,其他情況參考post請(qǐng)求。
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; }
上述就是小編為大家分享的使用C#怎么對(duì)WebApi 接口進(jìn)行傳參了,如果剛好有類(lèi)似的疑惑,不妨參照上述分析進(jìn)行理解。如果想知道更多相關(guān)知識(shí),歡迎關(guān)注億速云行業(yè)資訊頻道。
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。