ASP.Net MVC开发基础学习笔记(5):区域、模板页与WebAPI初步
http://blog.jobbole.com/85008/
ASP.Net MVC開發基礎學習筆記(5):區域、模板頁與WebAPI初步
分享到: 原文出處:?Edison Chou的博客(@周旭龍EdisonChou)???- 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:
| GetAllProducts | /api/product |
| GetProductById | /api/product/id |
| GetProductsByCategory | /api/product/?category=category |
客戶端可以通過URI來訪問我們的控制器已達到對資源的操作,那么,我們可以設計一個頁面來發送AJAX請求來實踐一下。
(7)在Views中的默認Home/Index這個頁面中,加入以下代碼:
XHTML| 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='#' οnclick='editProduct(" + value.Id + ")'>編輯</a><a href='#' οnclick='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='#' οnclick='editProduct(" + value.Id + ")'>編輯</a><a href='#' οnclick='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='#' οnclick='editProduct(" + data.Id + ")'>編輯</a><a href='#' οnclick='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='#' οnclick='editProduct(" + value.Id + ")'>編輯</a><a href='#' οnclick='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
轉載于:https://www.cnblogs.com/wangluochong/p/7409256.html
總結
以上是生活随笔為你收集整理的ASP.Net MVC开发基础学习笔记(5):区域、模板页与WebAPI初步的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: UVA 1210 Sum of Cons
- 下一篇: 在ASP.NET MVC中加载部分视图的