今天學習一下:WebAPI如何使用呢?
首先我們打開vs新建一個WebAPI項目,可以看到一共有這些文件夾目錄
首先了解一下這些文件夾/文件的意義(按照程序啟動的流程,相關的配置項就不說了),
Global.asax:這個是程序啟動的文件,內部的默認方法【Application_Start】對文件綁定、WebAPI路由、mvc控制器路由等進行注冊,只會在第一個用戶訪問的時候運行;上網找了一下相關資料,發現可以在其中添加很多的配置方法:
1 using System; 2 using System.Collections.Generic; 3 using System.IO; 4 using System.Linq; 5 using System.Text; 6 using System.Web; 7 using System.Web.Http; 8 using System.Web.Mvc; 9 using System.Web.Optimization; 10 using System.Web.Routing; 11 12 namespace AAAAAA.WebAPI 13 { 14 /// <summary> 15 /// WebApi全局設置 16 /// </summary> 17 public class WebApiApplication : System.Web.HttpApplication 18 { 19 /// <summary> 20 /// 第一個訪問網站的用戶會觸發該方法. 通常會在該方法里定義一些系統變量 21 /// 如聊天室的在線總人數統計,歷史訪問人數統計的初始化等等均可在這里定義. 22 /// </summary> 23 protected void Application_Start() 24 { 25 26 } 27 28 /// <summary> 29 /// 在應用程序關閉時運行的代碼,在最后一個HttpApplication銷毀之后執行 30 /// 比如IIS重啟,文件更新,進程回收導致應用程序轉換到另一個應用程序域 31 /// </summary> 32 /// <param name="sender"></param> 33 /// <param name="e"></param> 34 void Application_End(object sender, EventArgs e) 35 { 36 37 } 38 39 /// <summary> 40 /// 每個用戶訪問網站的第一個頁面時觸發; 41 /// </summary> 42 /// <param name="sender"></param> 43 /// <param name="e"></param> 44 void Session_Start(object sender, EventArgs e) 45 { 46 string IP = this.Context.Request.UserHostAddress; 47 Session["IP"] = IP; 48 } 49 50 /// <summary> 51 /// 使用了session.abandon(),或session超時用戶退出后均可觸發. 52 /// </summary> 53 /// <param name="sender"></param> 54 /// <param name="e"></param> 55 void Session_End(object sender, EventArgs e) 56 { 57 // Session["User"]; 向數據庫中記錄用戶退出時間 58 } 59 /// <summary> 60 /// 在每一個HttpApplication實例初始化的時候執行 61 /// </summary> 62 /// <param name="sender"></param> 63 /// <param name="e"></param> 64 void Application_Init(object sender, EventArgs e) 65 { 66 67 } 68 69 /// <summary> 70 /// 在應用程序被關閉一段時間之后,在.net垃圾回收器准備回收它占用的內存的時候被調用。 71 ///在每一個HttpApplication實例被銷毀之前執行 72 /// </summary> 73 /// <param name="sender"></param> 74 /// <param name="e"></param> 75 void Application_Disposed(object sender, EventArgs e) 76 { 77 78 } 79 80 /// <summary> 81 ///所有沒有處理的錯誤都會導致這個方法的執行 82 /// </summary> 83 /// <param name="sender"></param> 84 /// <param name="e"></param> 85 void Application_Error(object sender, EventArgs e) 86 { 87 #region 記錄錯誤日志 88 //Exception ex = Server.GetLastError().GetBaseException(); 89 //StringBuilder str = new StringBuilder(); 90 //str.Append("\r\n" + DateTime.Now.ToString("yyyy.MM.dd HH:mm:ss")); 91 //str.Append("\r\n.客戶信息:"); 92 93 94 //string ip = ""; 95 //if (Request.ServerVariables.Get("HTTP_X_FORWARDED_FOR") != null) 96 //{ 97 // ip = Request.ServerVariables.Get("HTTP_X_FORWARDED_FOR").ToString().Trim(); 98 //} 99 //else 100 //{ 101 // ip = Request.ServerVariables.Get("Remote_Addr").ToString().Trim(); 102 //} 103 //str.Append("\r\n\tIp:" + ip); 104 //str.Append("\r\n\t瀏覽器:" + Request.Browser.Browser.ToString()); 105 //str.Append("\r\n\t瀏覽器版本:" + Request.Browser.MajorVersion.ToString()); 106 //str.Append("\r\n\t操作系統:" + Request.Browser.Platform.ToString()); 107 //str.Append("\r\n.錯誤信息:"); 108 //str.Append("\r\n\t頁面:" + Request.Url.ToString()); 109 //str.Append("\r\n\t錯誤信息:" + ex.Message); 110 //str.Append("\r\n\t錯誤源:" + ex.Source); 111 //str.Append("\r\n\t異常方法:" + ex.TargetSite); 112 //str.Append("\r\n\t堆棧信息:" + ex.StackTrace); 113 //str.Append("\r\n--------------------------------------------------------------------------------------------------"); 114 ////創建路徑 115 //string upLoadPath = Server.MapPath("~/Logs/"); 116 //if (!System.IO.Directory.Exists(upLoadPath)) 117 //{ 118 // System.IO.Directory.CreateDirectory(upLoadPath); 119 //} 120 ////創建文件 寫入錯誤 121 //System.IO.File.AppendAllText(upLoadPath + DateTime.Now.ToString("yyyy.MM.dd") + ".log", str.ToString(), System.Text.Encoding.UTF8); 122 ////處理完及時清理異常 123 //Server.ClearError(); 124 ////跳轉至出錯頁面 125 //Response.Redirect("Error.html"); 126 #endregion 127 } 128 129 130 /// <summary> 131 /// //每次請求時第一個出發的事件,這個方法第一個執行 132 /// </summary> 133 /// <param name="sender"></param> 134 /// <param name="e"></param> 135 void Application_BeginRequest(object sender, EventArgs e) 136 { 137 var url =Request.Url.ToString(); 138 139 } 140 141 /// <summary> 142 ///在執行驗證前發生,這是創建驗證邏輯的起點 143 /// </summary> 144 /// <param name="sender"></param> 145 /// <param name="e"></param> 146 void Application_AuthenticateRequest(object sender, EventArgs e) 147 { 148 149 } 150 151 /// <summary> 152 /// 當安全模塊已經驗證了當前用戶的授權時執行 153 /// </summary> 154 /// <param name="sender"></param> 155 /// <param name="e"></param> 156 void Application_AuthorizeRequest(object sender, EventArgs e) 157 { 158 159 } 160 161 /// <summary> 162 /// 當ASP.NET完成授權事件以使緩存模塊從緩存中為請求提供服務時發生,從而跳過處理程序(頁面或者是WebService)的執行。 163 ///這樣做可以改善網站的性能,這個事件還可以用來判斷正文是不是從Cache中得到的。 164 /// </summary> 165 /// <param name="sender"></param> 166 /// <param name="e"></param> 167 void Application_ResolveRequestCache(object sender, EventArgs e) 168 { 169 170 } 171 172 /// <summary> 173 /// 讀取了Session所需的特定信息並且在把這些信息填充到Session之前執行 174 /// </summary> 175 /// <param name="sender"></param> 176 /// <param name="e"></param> 177 void Application_AcquireRequestState(object sender, EventArgs e) 178 { 179 180 } 181 182 /// <summary> 183 /// 在合適的處理程序執行請求前調用 184 ///這個時候,Session就可以用了 185 /// </summary> 186 /// <param name="sender"></param> 187 /// <param name="e"></param> 188 void Application_PreRequestHandlerExecute(object sender, EventArgs e) 189 { 190 191 } 192 193 194 /// <summary> 195 ///當處理程序完成對請求的處理后被調用。 196 /// </summary> 197 /// <param name="sender"></param> 198 /// <param name="e"></param> 199 void Application_PostRequestHandlerExecute(object sender, EventArgs e) 200 { 201 202 } 203 204 /// <summary> 205 /// 釋放請求狀態 206 /// </summary> 207 /// <param name="sender"></param> 208 /// <param name="e"></param> 209 void Application_ReleaseRequestState(object sender, EventArgs e) 210 { 211 212 } 213 214 /// <summary> 215 /// 為了后續的請求,更新響應緩存時被調用 216 /// </summary> 217 /// <param name="sender"></param> 218 /// <param name="e"></param> 219 void Application_UpdateRequestCache(object sender, EventArgs e) 220 { 221 222 } 223 224 /// <summary> 225 /// EndRequest是在響應Request時最后一個觸發的事件 226 ///但在對象被釋放或者從新建立以前,適合在這個時候清理代碼 227 /// </summary> 228 /// <param name="sender"></param> 229 /// <param name="e"></param> 230 void Application_EndRequest(object sender, EventArgs e) 231 { 232 233 } 234 235 /// <summary> 236 /// 向客戶端發送Http標頭之前被調用 237 /// </summary> 238 /// <param name="sender"></param> 239 /// <param name="e"></param> 240 void Application_PreSendRequestHeaders(object sender, EventArgs e) 241 { 242 243 } 244 245 /// <summary> 246 /// 向客戶端發送Http正文之前被調用 247 /// </summary> 248 /// <param name="sender"></param> 249 /// <param name="e"></param> 250 void Application_PreSendRequestContent(object sender, EventArgs e) 251 { 252 253 } 254 } 255 }
App_Start:這里面主要是程序啟動的時候需要進行的一下注冊文件,比如路由,文件篩選什么的;
其他的就不介紹了。
打開框架默認提供的控制器【ValuesController】,可以看到內部提供了5個demo,分別是無參Get,帶參Get,Post,Put,Delete的請求方式,其中Post和Put的例子參數都是帶有【FromBody】特性,這里介紹一下【FromBody】和【FromUrl】;
【FromBody】:強制接口從FormData中讀取數據;
【FromUrl】:強制接口從Uri中讀取數據。
webApi的路由我們可以看到
控制器之后是直接帶參數的,程序是如何根據路由找到對應的接口的呢?WebApi是遵循RESTful設計風格的,webapi會根據請求方式的不同來自動尋找對應的接口,如果一個webAPI控制器內部對於同樣的請求方式有多個接口,那么webapi默認路由會找不到對應的接口而報錯,如果要遵循RESTful風格,可能需要對每個業務的接口進行控制器隔離。
那么如果需要改變這種請求方式,變成和MVC類似的請求,應該如何修改呢?
我們需要將webapi添加一個路由機制:
這樣我們就可以使用mvc模式的路由或者webapi默認路由進行接口的調用了。
WebApi是遵循Restful風格的,所以不建議在路由中出現action,不推薦使用和MVC控制器相同格式的路由
那么使用webapi有哪些地方需要注意呢?
1.ajax中的type有四種方式:get(查詢),post(修改),delete(刪除),put(插入) 。
2.寫webapi時,在后台的方法最好將特性標記號對應上[HttpGet],[HttpPost],[HttpDelete],[HttpPut]。http請求和rest風格的api如果不想在后台方法寫特性,但也可以將方法名以Get開頭,否則會報錯。
get:若是查詢數據,通過get,其實get請求會將參數拼裝到url上面,而url長度是有限的
post:若是對原有數據新增和修改就用post,多用post即可。post不是將參數放在url上面的,而是放在表單上的。
3.傳遞的參數username名一定要相同,但是大小寫可以不一樣。
4.若是user={name:"張蘇納",id:123,age:'19'} 然后data:user那么在后台是接收不到的,即使在頁面調試時是可以看到數據。若是想接收到的話,需要在后台寫成GetUserModeuri([FormUri]Users user)。
5.基於第4的另一種方法。可以將user序列化轉化為一個字符竄,然后后台接收后反序列化即可得到。data:{userString:JSON.stringify(user)}
6.(1)若是通過post請求的時候,是將數據放在from data里面的,若是傳遞單個參數,不要在ajax上不要寫對應參數。
(2)只有不寫id才能得到,與[formbody]無關。若是通過post傳遞實體,那么在后台可以直接拿到 ,不需要任何轉化。
(3)當然也可以通過data:Json.stringify(user) contentType:'application/json'(contentType默認是json類型的)來在后台同樣得到。
(4)若是參數包含了一個實體,還有一個字符串參數data:{"User":user,"Info":info}該怎么辦,可以通過引用Newtonsoft.Json.Linq的JObject類型。jObject.ToObject是一個序列化方法,將josn轉化為對象。
7.dynamic動態類型,比如一個實體和一個參數放到同一個對象中,獲取對象后,然后dynamic json=jData; var mm= json.user,動態類型是可以直接訪問屬性的。
8.put和post是一樣的使用,put主要是插入數據使用。
9.delete也是一樣的。
10.webapi最方便的是給前端使用。