- ASP.Net MVC開發基礎學習筆記:一、走向MVC模式
- ASP.Net MVC開發基礎學習筆記:二、HtmlHelper與擴充套件方法
- ASP.Net MVC開發基礎學習筆記:三、Razor檢視引擎、控制器與路由機制學習
- ASP.Net MVC開發基礎學習筆記:四、校驗、AJAX與過濾器
一、區域—麻雀雖小,五臟俱全的迷你MVC專案
1.1 Area的興起
為了方便大規模網站中的管理大量檔案,在ASP.NET MVC 2.0版本中引入了一個新概念—區域(Area)。
在專案上右擊建立新的區域,可以讓我們的專案不至於太複雜而導致管理混亂。有了區域後,每個模組的頁面都放入相應的區域內進行管理很方便。例如:上圖中有兩個模組,一個是Admin模組,另一個是Product模組,所有關於這兩個模組的控制器、Model以及檢視都放入各自的模組內。可以從上圖中看出,區域的功能類似一個小的MVC專案,麻雀雖小五臟俱全,有自己的控制器、模型、檢視還有路由設定。
區域實際上是應用程式內部的一個 MVC 結構,一個應用程式可能包含若干個 MVC 結構(區域)。例如:一個大型電子商務應用程式可能分為若干個區域,這些區域表示店面、產品檢查、使用者帳戶管理和採購系統。每個區域表示整個應用程式的一個獨立功能。
1.2 註冊區域路由
在MVC中新增一個Area區域之後,會預設幫我們註冊這個區域的路由規則。例如:我們建立了一個Admin的區域,然後它幫我們生成了一個AdminAreaRegistration.cs的檔案,其程式碼如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
public class AdminAreaRegistration : AreaRegistration { public override string AreaName { get { return "Admin"; } } public override void RegisterArea(AreaRegistrationContext context) { context.MapRoute( "Admin_default", "Admin/{controller}/{action}/{id}", new { action = "Index", id = UrlParameter.Optional } ); } } |
這裡,RegisterArea是實現註冊的關鍵方法,通過把另一個路由新增到區域路由集合中實現。請注意,這裡的區域名Admin是以硬編碼方式新增到URL中;因此,所有使用此區域名稱作為字首的請求都被進行特別路由處理。
你可能感到疑惑:為什麼我們不能在主應用程式的路由定義中指定Admin部分?實際上,如果我們將它加入到標準的路由表中,而不通過區域上下文(AreaRegistrationContext),那麼我們還是把所有檔案駐留到同一個專案中,從而失去了分離專案區域的好處(即區域沒有起到作用)。
二、模板頁—封裝頁面變化點,構建快速View開發模板
在傳統的WebForm開發模式中,我們使用MasterPage作為模板頁。那麼在MVC3 Razor檢視設計中,我們怎麼來使用模板頁呢?
2.1 模板頁的歸宿—Shared資料夾
在解決方案資源管理中,我們可以看到Views資料夾下面有一個Shared資料夾。在Shared資料夾裡面有一個_Layout.cshtml頁面。這個就是專案中預設的模板頁面,如下圖所示:
在Shared中新建一個MVC佈局頁,取名為:_MyLayout.cshtml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
<!DOCTYPE html> <html> <head> <meta name="viewport" content="width=device-width" /> <title>@ViewBag.Title</title> </head> <body> <div> @RenderSection("Head", required: false) <h1>This is MyLayout Page</h1> <hr /> @RenderBody() </div> </body> </html> |
其中RenderSection為渲染指定區域,該區域名稱為Head,但不是必須渲染(required:false)。而RenderBody則是重頭戲,他就類似於MasterPage中主內容的PlaceHolder,是每個使用該模板頁都需填充的內容區域。
那麼,怎麼來使用這個模板頁呢?其實很簡單,只需要在要使用模板頁的View中修改Layout屬性即可:
2.2 View未動,ViewStart先行
在Razor檢視引擎中,所有頁面啟動之前,ViewStart檔案會先執行。那麼,這個ViewStart檔案到底做了些什麼事兒呢?
(1)可以看出,這個ViewStart是一個全域性的頁面。當我們的頁面未指定Layout的時候,如果專案在全域性或在同資料夾記憶體在_ViewStart.cshtml時該頁面的Layout會自動繼承自_ViewStart.cshtml,如果不同的資料夾層級都存在_ViewStart.cshtml,則繼承離該頁面最近的一個。
(2)如果我們想要所有的頁面都預設使用一個指定模板頁,只需將這個Layout改為新模板頁即可。例如:將Layout改為我們剛剛建立的~/Views/Shared/_MyLayout.cshtml。
2.3 RenderBody與RenderSection
(1)RenderBody:
@RenderBody()在模板頁中使用表示內容頁在模板中的位置。當建立具有模板頁的內容頁的時候,內容頁就呈現在模板頁中@RenderBody()所在的位置,一個模板頁中只能有一個@RenderBody()。
(2)RenderSection:
@RenderSection用於在模板佈局中定義一個區域,在內容頁可以定義一些內容來填充這個區域,例如內容頁中引用的JS檔案,可以填充到模板頁的section位置。每個內容頁的單獨一些資訊,可以在模板頁中這個區域顯示。
@RenderSection有兩個個引數,第一個引數用於定義section的名稱,第2個引數是布林型別,如果為TRUE,表示內容頁必須定義這個section,如果為false,則表示內容頁可定義section,也可以不定義。
三、WebAPI初步—構建輕量級Restful服務的利器
3.1 Restful架構是什麼?
RESTful架構,就是目前最流行的一種網際網路軟體架構。它結構清晰、符合標準、易於理解、擴充套件方便,所以正得到越來越多網站的採用。
這裡借用阮一峰博士的總結,到底什麼是Restful架構:
(1)每一個URI代表一種資源;
(2)客戶端和伺服器之間,傳遞這種資源的某種表現層;
(3)客戶端通過四個HTTP動詞,對伺服器端資源進行操作,實現”表現層狀態轉化“。
各位園友可以閱讀阮一峰博士的這篇《理解RESTful架構》的文章來了解Restful架構的基本概念。
綜上所示,REST是一種簡潔的設計風格,通過URL來設計系統,以URI來抽象各種資源,以HTTP協議的PUT、DELETE、GET、POST來對應對資源的各種操作。
3.2 WCF and WebAPI
首先,ASP.NET Web API 和WCF有著千絲萬縷的聯絡。
WCF是一個通用的服務架構平臺,其設計之初在於建立一個通用的Web Service平臺,可以在各種不同的協議(TCP, UDP, HTTP)下使用,僅僅通過EndPoint的配置而不需要修改程式碼實現就能適應不同的工作環境。WCF也是微軟以前很多服務產品的合體。
WCF 裡面可以採用模板的方式來實現REST架構風格,但WCF畢竟是一個集大成的平臺(或者說是:比較重量級)。WCF的野心造成了它的龐大複雜,HTTP的單純造就了它的簡單優美。於是經常自問:拿著牛刀削蘋果有必要嗎?廢話,當然沒有必要,水果刀在哪裡?因此,我們所需要的僅僅是裡面HTTP REST風格的部分。各種因素糾結下,微軟於是便把WCF裡面的這部分團隊抽離出來合併到了MVC組中,才有了現在的ASP.NET Web API,幷包含在MVC 4中釋出。
3.3 第一個WebAPI專案
(1)新建一個ASP.NET MVC專案,取名為:MyMvcWebAPIDemo,專案型別選擇WebAPI。
(2)在Models中新增一個類,取名為:Product,作為我們要測試的實體模型。
1 2 3 4 5 6 7 |
public class Product { public int Id { get; set; } public string Name { get; set; } public string Category { get; set; } public decimal Price { get; set; } } |
(3)在Controllers中新增一個控制器,並選擇“空WebAPI”型別模板,取名為:ProductController。
(4)為了方便進行資料測試,這裡定義一個靜態的產品集合。當然,在實際應用中,我們可能會從資料庫中讀取資料集合,並對其進行增刪查改及各種查詢操作。
1 2 3 4 5 6 7 8 |
static List<Product> products = new List<Product> { new Product { Id = 1, Name = "Nokia Lumia 1520", Category = "行動電話", Price = 3500 }, new Product { Id = 2, Name = "Lenovo Thinkpad T430S", Category = "行動式計算機", Price = 8000 }, new Product { Id = 3, Name = "錘子手機", Category = "行動電話", Price = 3300 } , new Product { Id = 4, Name = "Wii", Category = "電視遊戲機", Price = 1000 }, new Product { Id = 5, Name = "Xbox 360", Category = "電視遊戲機", Price = 3200 } }; |
(5)定義一些方法,用於對產品集合的各種操作:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 |
public class ProductController : ApiController { static List<Product> products = new List<Product> { new Product { Id = 1, Name = "Nokia Lumia 1520", Category = "行動電話", Price = 3500 }, new Product { Id = 2, Name = "Lenovo Thinkpad T430S", Category = "行動式計算機", Price = 8000 }, new Product { Id = 3, Name = "錘子手機", Category = "行動電話", Price = 3300 } , new Product { Id = 4, Name = "Wii", Category = "電視遊戲機", Price = 1000 }, new Product { Id = 5, Name = "Xbox 360", Category = "電視遊戲機", Price = 3200 } }; /// <summary> /// GET /// </summary> /// <returns></returns> public IEnumerable<Product> GetAllProducts() { return products.OrderBy(p => p.Id); } /// <summary> /// GET /// </summary> /// <param name="id"></param> /// <returns></returns> public Product GetProductById(int id) { Product product = products.FirstOrDefault(p => p.Id == id); if (product == null) { var resp = new HttpResponseMessage(HttpStatusCode.NotFound); throw new HttpResponseException(resp); } return product; } /// <summary> /// GET /// </summary> /// <param name="productName">產品名</param> /// <returns></returns> public Product GetProductByName(string productName) { Product product = products.FirstOrDefault(p => p.Name.Contains(productName)); if (product == null) { var resp = new HttpResponseMessage(HttpStatusCode.NotFound); throw new HttpResponseException(resp); } return product; } /// <summary> /// GET /// </summary> /// <param name="category">型別名稱</param> /// <returns></returns> public IEnumerable<Product> GetAllProductsByCategory(string category) { if (category.Equals("--請選擇--")) { return products; } IEnumerable<Product> productList = products.Where( p => string.Equals(p.Category, category, StringComparison.OrdinalIgnoreCase)); return productList.OrderBy(p => p.Id); } /// <summary> /// POST /// </summary> /// <returns></returns> public bool PostProduct(Product product) { int index = products.FindIndex(p => p.Name == product.Name); if (index != -1) { return false; } product.Id = products.Max(p => p.Id) + 1; products.Add(product); return true; } /// <summary> /// PUT /// </summary> /// <returns></returns> public bool PutProduct(int id, [FromBody]Product product) { int index = products.FindIndex(p => p.Id == id); if (index == -1) { return false; } products.RemoveAt(index); products.Add(product); return true; } /// <summary> /// DELETE /// </summary> /// <returns></returns> public bool DeleteProduct(int id) { Product product = products.FirstOrDefault(p => p.Id == id); if (product == null) { return false; } products.Remove(product); return true; } } |
一般來說,Http的四種訪問型別中,Get:一般用作查詢,多次操作得到結果一致;Post:一般用於修改、新增多次重複操作得到結果不一致。Put:一般用於修改,多次操作得到結果一致。Delete:一般用於刪除資料,多次操作得到結果一致。
現在,我們來看一下我們寫的這些方法:
①用於GET方式獲取的方法有:
GetAllProducts用於獲取所有產品的集合;GetProductById用於返回指定Id的產品物件;
GetProductByName使用者返回指定Name的產品物件;GetAllProductsByCategory則使用者返回指定Category(種類)的產品集合;
②用於POST方式的方法有:
PostProduct用於增加一個產品資訊;
③用於PUT方式的方法有:
PutProduct用於修改一個指定的產品資訊;
④用於DELETE方式的方法有:
DeleteProduct用於刪除一個選擇的產品資訊;
以上GET、POST、PUT、DELETE則構成了我們通過HTTP協議對資源的各種操作了。具體的程式碼,這裡我就不過多贅述,相信大家都能看懂。
(6)此時,我們有了一個能工作的Web API了。該控制器上的每個方法都對映到一個URI,例如下表中所示的前三個方法所對應的URI:
Controller Method 控制器方法 |
URI |
---|---|
GetAllProducts | /api/product |
GetProductById | /api/product/id |
GetProductsByCategory | /api/product/?category=category |
客戶端可以通過URI來訪問我們的控制器已達到對資源的操作,那麼,我們可以設計一個頁面來傳送AJAX請求來實踐一下。
(7)在Views中的預設Home/Index這個頁面中,加入以下程式碼:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 |
<link href="~/Content/themes/easyui/bootstrap/easyui.css" rel="stylesheet" /> <link href="~/Content/themes/easyui/icon.css" rel="stylesheet" /> <header> <div class="content-wrapper"> <div class="float-left"> <p class="site-title"> <a href="~/">ASP.NET Web API</a> </p> </div> </div> </header> <div id="body"> <section class="featured"> <div class="content-wrapper"> @*<hgroup class="title"> <h1>歡迎使用 ASP.NET Web API!</h1> <h2>這是一個簡單的WebAPI入門Demo.</h2> </hgroup>*@ <p> <strong>搜尋:</strong> ①產品型別: <select id="productTypes" name="productTypes" style="width: 120px; height: 34px;"> <option value="-1">--請選擇--</option> <option value="0">行動電話</option> <option value="1">行動式計算機</option> <option value="2">電視遊戲機</option> </select> ②產品名稱:<input id="productName" name="productName" type="text" /> <input id="btnSearchByName" name="btnSearchByName" type="button" value="搜 索" /> <input id="btnSearchAll" name="searchAll" type="button" value="全 部" /> </p> <p> <strong>新增:</strong> <br /> 產品名稱:<input id="newProductName" name="newProductName" type="text" /> 產品型別:<select id="newProductType" name="newProductType" style="width: 120px; height: 34px;"> <option value="-1">--請選擇--</option> <option value="0">行動電話</option> <option value="1">行動式計算機</option> <option value="2">電視遊戲機</option> </select> <br /> 產品價格:<input id="newProductPrice" name="newProductPrice" type="text" /> <input id="btnPostProduct" name="btnPostProduct" type="button" value="新 增" /> </p> </div> </section> <section class="content-wrapper main-content clear-fix"> <h3>下面是從WebAPI獲取的資料集:</h3> <div id="result"> </div> @*<ol class="round"> <li class="one"> <h5>開始使用</h5> ASP.NET Web API 是一個框架,您可以通過該框架輕鬆生成可訪問 多種客戶端(包括瀏覽器和移動裝置)的 HTTP 服務。ASP.NET Web API 是一個用於在 .NET Framework 之上生成 REST 樣式的應用程式的理想平臺。 <a href="http://go.microsoft.com/fwlink/?LinkId=245160">瞭解詳細資訊...</a> </li> </ol>*@ </section> </div> <!-- jBox modal --> <div id="myMsgModal" class="notshow"> </div> <!-- jBox edit modal --> <div id="myEditModal" class="notshow"> <input id="hiddProductId" type="hidden" /> <table width="100%"> <tr> <td align="right">產品名稱:</td> <td> <input id="editProductName" name="editProductName" type="text" /></td> </tr> <tr> <td align="right">產品型別:</td> <td> <select id="editProductType" name="editProductType" style="width: 120px; height: 34px;"> <option value="-1">--請選擇--</option> <option value="0">行動電話</option> <option value="1">行動式計算機</option> <option value="2">電視遊戲機</option> </select> </td> </tr> <tr> <td align="right">產品價格:</td> <td> <input id="editProductPrice" name="editProductPrice" type="text" /> </td> </tr> <tr> <td colspan="2" align="center"> <a id="btnPutProduct" href="#" class="easyui-linkbutton">確定</a> <a id="btnCloseModal" href="#" class="easyui-linkbutton">關閉</a> </td> </tr> </table> </div> @section scripts{ <script src="~/Scripts/jquery-1.7.1.min.js"></script> <script src="~/Content/themes/easyui/jquery.easyui.min.js"></script> <script src="~/Content/themes/easyui/easyui-lang-zh_CN.js"></script> <script type="text/javascript"> $(function () { initData(); bindClick(); }); function initData() { $.getJSON("api/Product", function (data) { if (data != null) { if ($("#resultList").length > 0) { $("#resultList").remove(); } var html = "<ol id='resultList' class='round'>"; $.each(data, function (key, value) { html += "<li class='one'><h5>" + value.Name + "</h5>型別:" + value.Category + " 價格:" + value.Price + " | <a href='#' onclick='editProduct(" + value.Id + ")'>編輯</a><a href='#' onclick='deleteProduct(" + value.Id + ")'>刪除</a></li>"; }); html += "</ol>"; $("#result").append(html); } }); } function bindClick() { // 01.按產品型別搜尋產品 $("#productTypes").bind("change", function () { $.getJSON("api/Product", { category: $(this).find("option:selected").text() }, function (data) { if (data != null) { $("#resultList").remove(); var html = "<ol id='resultList' class='round'>"; $.each(data, function (key, value) { html += "<li class='one'><h5>" + value.Name + "</h5>型別:" + value.Category + " 價格:" + value.Price + " | <a href='#' onclick='editProduct(" + value.Id + ")'>編輯</a><a href='#' onclick='deleteProduct(" + value.Id + ")'>刪除</a></li>"; }); html += "</ol>"; $("#result").append(html); } }); }); // 02.按產品名搜尋產品 $("#btnSearchByName").bind("click", function () { var searchName = $("#productName").val(); if (searchName == "") { showMsg("提示", "您還沒有輸入要搜尋的產品名稱"); } $.getJSON("api/Product", { productName: searchName }, function (data) { if (data != null) { $("#resultList").remove(); var html = "<ol id='resultList' class='round'>"; html += "<li class='one'><h5>" + data.Name + "</h5>型別:" + data.Category + " 價格:" + data.Price + " | <a href='#' onclick='editProduct(" + data.Id + ")'>編輯</a><a href='#' onclick='deleteProduct(" + data.Id + ")'>刪除</a></li>"; html += "</ol>"; $("#result").append(html); clearText(); } }); }); // 03.搜尋全部產品資訊 $("#btnSearchAll").bind("click", initData); // 04.新增一個產品資訊 $("#btnPostProduct").bind("click", function () { var productName = $("#newProductName").val(); var productCategory = $("#newProductType").find("option:selected").text(); var productPrice = $("#newProductPrice").val(); if (productName == "") { showMsg("提示", "請輸入產品名稱"); } else if (productCategory == "" || productCategory == "--請選擇--") { showMsg("提示", "請選擇產品型別"); } else if (productPrice == "") { showMsg("提示", "請輸入產品價格"); } else if (isNaN(productPrice)) { showMsg("提示", "產品價格請輸入數字型別"); } else { $.post("api/Product", { Name: productName, Category: productCategory, Price: productPrice }, function (data) { if (data != null && data == true) { initData(); clearText(); showMsg("提示", "新增新產品操作成功"); } else { showMsg("提示", "新增新產品操作失敗"); } }); } }); // 07.修改一個產品資訊 $("#btnPutProduct").bind("click", function () { var productId = $("#hiddProductId").val(); $.ajax({ type: "PUT", url: "/api/Product/" + productId, data: { Id: productId, Name: $("#editProductName").val(), Category: $("#editProductType").find("option:selected").text(), Price: $("#editProductPrice").val() }, success: function (data) { if (data == true) { initData(); $("#myEditModal").window("close"); showMsg("提示", "您已成功修改那玩意"); } else { showMsg("提示", "修改那玩意操作失敗"); } } }); }); // 關閉模態對話方塊 $("#btnCloseModal").bind("click", function () { $("#myEditModal").window("close"); }); } // 05.編輯一個產品資訊 function editProduct(productId) { $.getJSON("api/Product", { id: productId }, function (data) { if (data != null) { $("#hiddProductId").val(data.Id); $("#editProductName").val(data.Name); switch (data.Category) { case "行動電話": $("#editProductType").val("0"); break; case "行動式計算機": $("#editProductType").val("1"); break; case "電視遊戲機": $("#editProductType").val("2"); break; } $("#editProductPrice").val(data.Price); } }); $("#myEditModal").show(); $("#myEditModal").window({ title: "編輯產品資訊", modal: true, collapsible: true, minimizable: false, maximizable: false, resizable: false, width: 500, height: 220 }); } // 06.刪除一個產品資訊 function deleteProduct(productId) { $.messager.confirm("提示", "您確定要刪除這玩意?", function (r) { if (r) { $.ajax({ type: "DELETE", url: "/api/Product/" + productId, data: {}, success: function (data) { if (data == true) { initData(); showMsg("提示", "您已成功刪除那玩意"); } else { showMsg("提示", "刪除那玩意操作失敗"); } } }); } }); } function showMsg(title, msg) { $.messager.alert(title, msg, "info"); } function clearText() { $("input[type=text]").val(""); } </script> } |
通過除錯執行,可以看到以下頁面效果,並可以看到,由於我們在頁面中加入了獲取產品列表的GET請求,於是產品資訊被載入到了頁面中:
其對應的JS語句為:可以看到,我們通過api/Product呼叫了API控制器中的GetAllProducts方法,獲取了所有產品資訊。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
$.getJSON("api/Product", function (data) { if (data != null) { if ($("#resultList").length > 0) { $("#resultList").remove(); } var html = "<ol id='resultList' class='round'>"; $.each(data, function (key, value) { html += "<li class='one'><h5>" + value.Name + "</h5>型別:" + value.Category + " 價格:" + value.Price + " | <a href='#' onclick='editProduct(" + value.Id + ")'>編輯</a><a href='#' onclick='deleteProduct(" + value.Id + ")'>刪除</a></li>"; }); html += "</ol>"; $("#result").append(html); } }); |
(8)下面我們可以來試試其他的API方法:
3.4 第一個RestClient客戶端專案
有了我們上面的WebAPI專案的支援,我們可以在客戶端(如:WindowsForm專案、Windows Phone專案等等)對WebAPI專案中的資源進行訪問和操作,現在我們就來實現一個RestClient控制檯專案模擬一個客戶端對WebAPI發起HTTP訪問請求。
(1)新建一個控制檯專案,取名為:MyConsoleRestClientDemo。
(2)新建一個類,取名為:RestClient.cs。它封裝了我們常用的HTTP操作,如GET、POST、PUT、DELETE方式。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 |
public class RestClient { private string BaseUri; public RestClient(string baseUri) { this.BaseUri = baseUri; } #region Delete方式 public string Delete(string data, string uri) { return CommonHttpRequest(data, uri, "DELETE"); } public string Delete(string uri) { //Web訪問物件64 string serviceUrl = string.Format("{0}/{1}", this.BaseUri, uri); HttpWebRequest myRequest = (HttpWebRequest)WebRequest.Create(serviceUrl); myRequest.Method = "DELETE"; // 獲得介面返回值68 HttpWebResponse myResponse = (HttpWebResponse)myRequest.GetResponse(); StreamReader reader = new StreamReader(myResponse.GetResponseStream(), Encoding.UTF8); //string ReturnXml = HttpUtility.UrlDecode(reader.ReadToEnd()); string ReturnXml = reader.ReadToEnd(); reader.Close(); myResponse.Close(); return ReturnXml; } #endregion #region Put方式 public string Put(string data, string uri) { return CommonHttpRequest(data, uri, "PUT"); } #endregion #region POST方式實現 public string Post(string data, string uri) { return CommonHttpRequest(data, uri, "POST"); } public string CommonHttpRequest(string data, string uri, string type) { //Web訪問物件,構造請求的url地址 string serviceUrl = string.Format("{0}/{1}", this.BaseUri, uri); //構造http請求的物件 HttpWebRequest myRequest = (HttpWebRequest)WebRequest.Create(serviceUrl); //轉成網路流 byte[] buf = System.Text.Encoding.GetEncoding("UTF-8").GetBytes(data); //設定 myRequest.Method = type; myRequest.ContentLength = buf.Length; myRequest.ContentType = "application/json"; myRequest.MaximumAutomaticRedirections = 1; myRequest.AllowAutoRedirect = true; // 傳送請求 Stream newStream = myRequest.GetRequestStream(); newStream.Write(buf, 0, buf.Length); newStream.Close(); // 獲得介面返回值 HttpWebResponse myResponse = (HttpWebResponse)myRequest.GetResponse(); StreamReader reader = new StreamReader(myResponse.GetResponseStream(), Encoding.UTF8); string ReturnXml = reader.ReadToEnd(); reader.Close(); myResponse.Close(); return ReturnXml; } #endregion #region GET方式實現 public string Get(string uri) { //Web訪問物件64 string serviceUrl = string.Format("{0}/{1}", this.BaseUri, uri); //構造一個Web請求的物件 HttpWebRequest myRequest = (HttpWebRequest)WebRequest.Create(serviceUrl); // 獲得介面返回值68 //獲取web請求的響應的內容 HttpWebResponse myResponse = (HttpWebResponse)myRequest.GetResponse(); //通過響應流構造一個StreamReader StreamReader reader = new StreamReader(myResponse.GetResponseStream(), Encoding.UTF8); //string ReturnXml = HttpUtility.UrlDecode(reader.ReadToEnd()); string ReturnXml = reader.ReadToEnd(); reader.Close(); myResponse.Close(); return ReturnXml; } #endregion } |
(3)在Program.cs中的Main方法中,呼叫RestClient類為我們提供的方法對WebAPI伺服器(這裡是本機:http://localhost:8080/)發起訪問:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 |
class Program { static string restfulServiceUri = "http://localhost:8080/"; static void Main(string[] args) { RestClient restClient = new RestClient(restfulServiceUri); #region 01.Get方式無引數請求 Console.WriteLine("----------------------獲取所有產品列表-----------------------"); string getResult = restClient.Get("api/Product"); Console.WriteLine(getResult); Console.WriteLine(); #endregion #region 02.Get方式帶引數請求 Console.WriteLine("----------------------獲取Id=1的產品資訊-----------------------"); string getByIdResult = restClient.Get("api/Product/1"); Console.WriteLine(getByIdResult); Console.WriteLine(); Console.WriteLine("----------------------獲取Name=錘子手機的產品資訊-----------------------"); string getByNameResult = restClient.Get("api/Product/?productName=錘子手機"); Console.WriteLine(getByNameResult); Console.WriteLine(); Console.WriteLine("----------------------獲取Category=行動電話的產品資訊-----------------------"); string getByTypeResult = restClient.Get("api/Product/?category=行動電話"); Console.WriteLine(getByTypeResult); Console.WriteLine(); #endregion #region 03.Post方式請求結果 //Console.WriteLine("----------------------新增一個產品資訊-----------------------"); //string jsonParam = @"{Id:""250"",Name:""小米2S"",Category:""行動電話"",Price:""1800""}"; //string postResult = restClient.Post(jsonParam, "api/Product"); //Console.WriteLine(postResult); //getResult = restClient.Get("api/Product"); //Console.WriteLine(getResult); //Console.WriteLine(); #endregion #region 04.Delete方式請求結果 //Console.WriteLine("----------------------刪除一個產品資訊-----------------------"); //string deleteId = "6"; //string deleteResult = restClient.Delete("api/Product/" + deleteId); //Console.WriteLine(deleteResult); //getResult = restClient.Get("api/Product"); //Console.WriteLine(getResult); //Console.WriteLine(); #endregion #region 05.Put方式請求結果 Console.WriteLine("----------------------修改一個產品資訊-----------------------"); string jsonParam = @"{Id:""5"",Name:""PlayStation 3"",Category:""電視遊戲機"",Price:""3200""}"; string putResult = restClient.Put(jsonParam, "api/Product/5"); Console.WriteLine(putResult); getResult = restClient.Get("api/Product"); Console.WriteLine(getResult); Console.WriteLine(); #endregion Console.ReadKey(); } } |
(4)除錯執行,檢視訪問結果如下:可以看出,返回的均為JSON格式的資料,和我們在瀏覽器中訪問指定URI的結果一致。
3.5 初探小結
ASP.NET Web API 是一種框架,用於輕鬆構建可以訪問多種客戶端(包括瀏覽器和移動裝置)的 HTTP 服務。 ASP.NET Web API 是一種用於在 .NET Framework 上構建 RESTful 應用程式的理想平臺。
參考文章
(1)搏擊的小船,《ASP.NET MVC2 Areas區域新概念》,http://www.cnblogs.com/guanjie20/archive/2010/09/09/1822175.html
(2)遊響雲停,《ASP.NET MVC3細嚼慢嚥-(2)模板頁 》,http://blog.csdn.net/zx13525079024/article/details/8301943
(3)李林峰,《無廢話MVC入門教程四[檢視中的Layout使用]》,http://www.cnblogs.com/iamlilinfeng/archive/2013/02/28/2934397.html
(4)阮一峰,《理解Restful架構》,http://www.ruanyifeng.com/blog/2011/09/restful.html
(5)便當之神,《ASP.Net WebAPI》,http://www.cnblogs.com/bnbqian/archive/2012/06/28/2565417.html
(6)dudu,《HttpClient + ASP.NET Web API, WCF之外的另一個選擇》,http://www.cnblogs.com/dudu/archive/2012/05/11/asp_net_webapi_httpclient.html
附件下載
(1)MyWebAPIDemo:http://pan.baidu.com/s/1hqzgwb6