asp.net MVC Web API 由於項目需要好久沒有弄這些重溫一下,以前都覺得WebServers好用 誰知道技能更新換代實在太快,哈哈不學習就跟不上了 ...
1、什麼是WebApi,它有什麼用途?
Web API是一個比較寬泛的概念。這裡我們提到Web API特指ASP.NET MVC Web API。在新出的MVC中,增加了WebAPI,用於提供REST風格的WebService,新生成的WebAPI項目和典型的MVC項目一樣,包含主要的Models、Views、Controllers等文件夾和Global.asax文件。Views對於WebAPI來說沒有太大的用途,Models中的Model主要用於保存Service和Client交互的對象,這些對象預設情況下會被轉換為Json格式的數據迚行傳輸,Controllers中的Controller對應於WebService來說是一個Resource,用於提供服務。和普通的MVC一樣,Global.asax用於配置路由規則,個人的理解MVC控制器中一般方法返回的是一個視圖而Api返回的是數據,可以是List、Json等格式。對於WebAPI來說它最初被設計為和WCF一樣的客戶埠、服務埠兩套結構我們到現在還沒有提到客戶埠是因為我們的請求別的方式來封裝成HTTP請求接收收HTTP相應的比如AJAX和Form表單提交。接下來我們用VS2017新建一個webApi項目。
2、打開VS2017 點文件-----> 新建---->項目。快捷鍵(Ctrl+Shift+N)
Web裡面的Asp.Net Web 應用程式
上面一定要選Web API 。項目建好了 我先做一個從資料庫取出數據在調用的慄子。
3、在控制器文件夾右鍵---->添加---->控制器。選擇Web API2 Controller Empty點確定取名Customer 因為後面要操作資料庫這張表 ,點add完成
這時候App_Satrt文件夾下麵多了一個文件WebApiConfig.cs,這個文件是它的路由
由於以前都是用原生的sql訪問資料庫 所以現在也說一下 原生的sql 在asp.net MVC中的使用不用EF連接 後面也使用EF
4、在Models文件夾下麵建立模型類Customer類與SqlDB類,這裡沒有分三層架構就簡單的寫在一起了理解就行(SqlDB類這裡有《Asp.Net中對操作Sql Server 簡單處理的SqlDB類》)
public class Customer { //ID public int ID { get; set; } //姓名 public string Name { get; set; } //學號 public string Number { get; set; } //性別1男2女 public int Sex { get; set; } //院系 public string Department { get; set; } //專業 public string Manjor { get; set; } //年級 public int Class { get; set; } //聯繫方式 public string Mobile { get; set; } }
在項目的web.config配置文件裡面一定要加資料庫連接字元串配置
<connectionStrings> <!--連接字元串--> <add name="SqlConn" connectionString=" Data Source=.;Initial Catalog=OneCardSystem;Integrated Security=True" /> </connectionStrings>
5、在API控制器裡面寫個方法返回List類型的數據
這個API控制器一定是繼承ApiController這個控制器的
public class CustomerController : ApiController { Customer customer = new Customer(); public List<Customer> GetCustomerAll() { //sql語句 string _sql = "Select * from Customer"; //實例SqlDB類 SqlDB sb = new SqlDB(); //定義List儲存 List<Customer> list = new List<Customer>(); //獲取數據 var data = sb.ExecuteDataSet(_sql).Tables[0].Rows; //遍歷data foreach(DataRow item in data) { var customer = new Customer() { //對應欄位 ID = Convert.ToInt32(item["ID"].ToString()), Number= item["Number"].ToString(), Name= item["Name"].ToString(), Manjor= item["Manjor"].ToString(), Mobile= item["Mobile"].ToString() }; //逐條添加到list裡面 list.Add(customer); } //返回list return list; } }
6、運行項目預設來到Home控制器所對應的視圖在地址欄後面加上/api/Customer/GetCustomerAll 就可以看到數據了 這個是在谷歌瀏覽器上面看到的結果,不同的瀏覽器有不同的效果 有時間自己試試看,API控制器訪問主要的就是在埠後面加上/api/控制器/方法名, 後面有參數的接上參數跟mvc一般的控制器我的理解就是就多了api的首碼
7、現在在瀏覽器裡面可以直接調用這個api了 ,接下來在一個項目中Home所對應的Index視圖裡面我們用前臺技術(jQuery getJSON)訪問調用一下試試
把引用的佈局我倒是刪除了,Views文件夾下麵的_ViewStart.cshtml 刪除了 Index.cshtml裡面的的內容也刪了
代碼在下麵 別忘了引用JS
<!DOCTYPE html> <html lang="en"> <head> <title>ASP.NET Web API</title> <script type="text/javascript" src="~/Scripts/jquery-3.3.1.js"></script> <script type="text/javascript"> $(document).ready(function () { $.getJSON("/api/Customer/GetCustomerAll", function (data) { // console.log(data); $.each(data, function (key, val) { $("#batMain").append("<tr><td>" + data[key].ID + "</td><td>" + data[key].Name + "</td><td>" + data[key].Number + "</td><td>" + data[key].Manjor + "</td><td><a class='tabEdit'>編輯</a> <a class='tabDele'>刪除</a></td></tr>"); Op(); }); }); $("#btnSave").click(function () { var id = $("#txtID").val(); var Name = $("#txtName").val(); var Number = $("#txtNumber").val(); var Manjor = $("#txtManjor").val(); var customer = { ID:id, Name:Name, Number:Number, Manjor:Manjor } $.ajax({ type: "post", url: "/api/Customer/Edit", // data: { "id": id, "Name": Name, "Number": Number, "Manjor": Manjor }, data: JSON.stringify(customer), contentType:"application/json", success: function (data) { console.log(data); }, error: function () { } }); }); }); function Op() { var id = ""; var row var tab = document.getElementById("batMain"); var edit = $(".tabEdit"); var dele = $(".tabDele"); for (var i = 0; i < edit.length; i++) { edit[i].onclick = function () { row = this.parentNode.parentNode.rowIndex; id = $("#batMain tr:eq(" + row + ") td:eq(0)").html(); $("#txtID").val($("#batMain tr:eq(" + row + ") td:eq(0)").html()); $("#txtName").val($("#batMain tr:eq(" + row + ") td:eq(1)").html()); $("#txtNumber").val($("#batMain tr:eq(" + row + ") td:eq(2)").html()); $("#txtManjor").val($("#batMain tr:eq(" + row + ") td:eq(3)").html()); } } } </script> <style type="text/css"> table{width:100%;} table tr td{text-align:center; line-height:20px; height:25px; min-width:80px; border:1px solid #d0cfcf;word-wrap:break-word;word-break:break-all;} a{list-style:none;font-size:12px;font-weight:600; color:#072af7;} a:hover{cursor:pointer} .trOne{background:rgb(202, 200, 212); line-height:40px; font-size:14px; font-weight:600;} </style> </head> <body id="body"> <div style="width:90%; margin: 0 auto;"> <h1>學生信息</h1> <table cellpadding="0" cellspacing="0"> <tr> <td width="20%"><input type="text" id="txtID" readonly="readonly" /></td> <td width="20%"><input type="text" id="txtName" /></td> <td width="20%"><input type="text" id="txtNumber" /></td> <td width="20%"><input type="text" id="txtManjor" /></td> <td width="20%"><input type="button" id="btnSave" value="確定" /></td> </tr> </table> <table cellpadding="0" cellspacing="0" id="batMain"> <tr class="trOne"> <td width="20%">ID</td> <td width="20%">姓名</td> <td width="20%">學號</td> <td width="20%">專業</td> <td width="20%">操作</td> </tr> </table> </div> </body> </html>
看看效果
這裡的編輯刪除操作我還沒有做完,不過一般的asp.net mvc我裡面用的是ajax請求後臺 這個不是請求API只是處理一般的增刪查改,這裡記錄一下傳值的問題
dada裡面可以是// data: { "id": id, "Name": Name, "Number": Number, "Manjor": Manjor },這樣的格式 後臺獲取直接用Request["ID"] 這樣子就可以獲取了。也可以在方法裡面定義對應的參數 ,參數名要跟data裡面的一樣
也可以傳值成一個對象過去 data: JSON.stringify(customer), 這樣 後臺接收 var stream = HttpContext.Request.InputStream; string JsonStr = new StreamReader(stream).ReadToEnd(); 然後自己解析一下
如果要在請求的API裡面傳參數我只能傳一個ID 其他的還沒有研究 要傳對象過去的話還要在方法裡面加上 ([FromBody] Customer ct)這樣
8、在後臺通過HttpClient調用API 我做練習的時候是用兩個項目 一個運行著 另一個調用這個 現在我弄在一個項目裡面 用控制器來請求。新建一個控制器Show右鍵Index添加視圖Index.cshyml
public class ShowController : Controller { // GET: Show public ActionResult Index() { //獲取埠 string url= Request.Url.ToString(); var httpClient = new HttpClient(); var data= httpClient.GetAsync(url+ "api/Customer/GetCustomerAll").Result.Content.ReadAsStringAsync().Result;//調用API System.Web.Script.Serialization. JavaScriptSerializer Serializer = new System.Web.Script.Serialization.JavaScriptSerializer(); List<Customer> objs = Serializer.Deserialize<List<Customer>>(data);//Json反序列化成List // Customer cs = JsonConvert.DeserializeObject<Customer>(cg.ReturnData); //, JsonRequestBehavior.AllowGet return View(objs); } }
視圖
對應的代碼
@{ ViewBag.Title = "Index"; } @using WebApiTest.Models; @model List<Customer> <html lang="en"> <head> <title>調用API</title> <style type="text/css"> table{width:100%;} table tr td{text-align:center; line-height:20px; height:25px; min-width:80px; border:1px solid #d0cfcf;word-wrap:break-word;word-break:break-all;} a{list-style:none;font-size:12px;font-weight:600; color:#072af7;} a:hover{cursor:pointer} .trOne{background:rgb(202, 200, 212); line-height:40px; font-size:14px; font-weight:600;} </style> </head> <body id="body"> <br /> <div style="width:90%; margin: 0 auto;"> <table> <tr class="trOne"> <td width="20%">ID</td> <td width="20%">姓名</td> <td width="30%">學號</td> <td width="30%">專業</td> </tr> @{ if(Model.Count>0) { foreach(var item in Model) { <tr> <td>@item.ID</td> <td>@item.Name</td> <td>@item.Number</td> <td>@item.Manjor</td> </tr> } } } </table> </div> </body> </html>
註意應用using System.Web.Script.Serialization; 沒有的話來這裡找
修改路由配置指向Show 控制器運行項目 你會看到
9、遇到的問題:
如果這裡你要返回一個Json數據 記得添加 return(objs, JsonRequestBehavior.AllowGet) 寫成這樣 具體什麼錯我也忘記了 JsonResult也是一樣的new 的時候一樣的添加後面的
如果在不同的項目中調用還要在配置文件裡面加下麵的代碼 加在<system.webServer>裡面 實在寫API的項目的配置文件裡面
<!--跨域配置--> <httpProtocol> <customHeaders> <add name="Access-Control-Allow-Origin" value="*" /> <add name="Access-Control-Max-Age" value="30" /> <add name="Access-Control-Allow-Methods" value="GET,POST,OPTIONS" /> <add name="Access-Control-Allow-Headers" value="Content-Type, Accept" /> </customHeaders> <tpProtocol> <handlers> <remove name="ExtensionlessUrlHandler-Integrated-4.0" /> <remove name="OPTIONSVerbHandler" /> <remove name="TRACEVerbHandler" /> <add name="ExtensionlessUrlHandler-Integrated-4.0" path="*." verb="*" type="System.Web.Handlers.TransferRequestHandler" preCondition="integratedMode,runtimeVersionv4.0" /> </handlers>
要是調試的時候出錯發現請求的路徑會自動的加上一個Home 在api前面記得在api裡面類名前面加 [RoutePrefix("Api/Customer")]