C#进阶之WebAPI(二)
今天學習一下: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.WebAPI13 {14 /// <summary>15 /// WebApi全局設置16 /// </summary>17 public class WebApiApplication : System.Web.HttpApplication18 {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最方便的是給前端使用。
總結
以上是生活随笔為你收集整理的C#进阶之WebAPI(二)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 一季度印度GDP增长3.1%,我国下降6
- 下一篇: c#进阶(7)—— 异步编程基础(asy