1.WebApi是什麼html
ASP.NET Web API 是一種框架,用於輕鬆構建能夠由多種客戶端(包括瀏覽器和移動設備)訪問的 HTTP 服務。ASP.NET Web API 是一種用於在 .NET Framework 上構建 RESTful 應用程序的理想平臺。jquery
能夠把WebApi當作Asp.Net項目類型中的一種,其餘項目類型諸如咱們熟知的WebForm項目,Windows窗體項目,控制檯應用程序等。ajax
WebApi類型項目的最大優點就是,開發者不再用擔憂客戶端和服務器之間傳輸的數據的序列化和反序列化問題,由於WebApi是強類型的,能夠自動進行序列化和反序列化,一下子項目中會見到。json
下面咱們創建了一個WebApi類型的項目,項目中對產品Product進行增刪改查,Product的數據存放在List<>列表(即內存)中。api
2.頁面運行效果瀏覽器
如圖所示,能夠添加一條記錄; 輸入記錄的Id,查詢出該記錄的其它信息; 修改該Id的記錄; 刪除該Id的記錄。服務器
3.二話不說,開始建項目app
1)新建一個「ASP.NET MVC 4 Web 應用程序」項目,命名爲「ProductStore」,點擊肯定,如圖框架
2)選擇模板「Web API」,點擊肯定,如圖post
3)和MVC類型的項目類似,構建程序的過程是先創建數據模型(Model)用於存取數據, 再創建控制器層(Controller)用於處理髮來的Http請求,最後構造顯示層(View)用於接收用戶的輸入和用戶進行直接交互。
這裏咱們先在Models文件夾中創建產品Product類: Product.cs,以下:
using System; using System.Collections.Generic; using System.Linq; using System.Web; namespace ProductStore.Models { public class Product { public int Id { get; set; } public string Name { get; set; } public string Category { get; set; } public decimal Price { get; set; } } }
4)試想,咱們目前只有一個Product類型的對象,咱們要編寫一個類對其實現增刪改查,之後咱們可能會增長其餘的類型的對象,再須要編寫一個對新類型的對象進行增刪改查的類,爲了便於拓展和調用,咱們在Product之上構造一個接口,使這個接口約定增刪改查的方法名稱和參數,因此咱們在Models文件夾中新建一個接口: IProductRepository.cs ,以下:
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace ProductStore.Models { interface IProductRepository { IEnumerable<Product> GetAll(); Product Get(int id); Product Add(Product item); void Remove(int id); bool Update(Product item); } }
5)而後,咱們實現這個接口,在Models文件夾中新建一個類,具體針對Product類型的對象進行增刪改查存取數據,並在該類的構造方法中,向List<Product>列表中存入幾條數據,這個類叫:ProductRepository.cs,以下:
using System; using System.Collections.Generic; using System.Linq; using System.Web; namespace ProductStore.Models { public class ProductRepository:IProductRepository { private List<Product> products = new List<Product>(); private int _nextId = 1; public ProductRepository() { Add(new Product { Name="Tomato soup",Category="Groceries",Price=1.39M}); Add(new Product { Name="Yo-yo",Category="Toys",Price=3.75M}); Add(new Product { Name = "Hammer", Category = "Hardware", Price = 16.99M }); } public IEnumerable<Product> GetAll() { return products; } public Product Get(int id) { return products.Find(p=>p.Id==id); } public Product Add(Product item) { if (item == null) { throw new ArgumentNullException("item"); } item.Id = _nextId++; products.Add(item); return item; } public void Remove(int id) { products.RemoveAll(p=>p.Id==id); } public bool Update(Product item) { if (item == null) { throw new ArgumentNullException("item"); } int index = products.FindIndex(p=>p.Id==item.Id); if (index == -1) { return false; } products.RemoveAt(index); products.Add(item); return true; } } }
此時,Model層就構建好了。
6)下面,咱們要構建Controller層,在此以前,先回顧一下Http中幾種請求類型,以下
get 類型 用於從服務器端獲取數據,且不該該對服務器端有任何操做和影響
post 類型 用於發送數據到服務器端,建立一條新的數據,對服務器端產生影響
put 類型 用於向服務器端更新一條數據,對服務器端產生影響 (也可建立一條新的數據但不推薦這樣用)
delete 類型 用於刪除一條數據,對服務器端產生影響
這樣,四種請求類型恰好可對應於對數據的 查詢,添加,修改,刪除。WebApi也推薦如此使用。在WebApi項目中,咱們請求的再也不是一個具體頁面,而是各個控制器中的方法(控制器也是一種類,默認放在Controllers文件夾中)。下面咱們將要創建一個ProductController.cs控制器類,其中的方法都是以「Get Post Put Delete」中的任一一個開頭的,這樣的開頭使得Get類型的請求發送給以Get開頭的方法去處理,Post類型的請求交給Post開頭的方法去處理,Put和Delete同理。
而以Get開頭的方法有好幾個也是能夠的,此時如何區分到底交給哪一個方法執行呢?這就取決於Get開頭的方法們的傳入參數了,一下子在代碼中能夠分辨。
構建Controller層,在Controllers文件夾中創建一個ProductController.cs控制器類,以下:
using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.Web.Mvc; using ProductStore.Models; using System.Web.Http; using System.Net; using System.Net.Http; namespace ProductStore.Controllers { public class ProductsController : ApiController { static readonly IProductRepository repository = new ProductRepository(); //GET: /api/products public IEnumerable<Product> GetAllProducts() { return repository.GetAll(); } //GET: /api/products/id public Product GetProduct(int id) { Product item = repository.Get(id); if (item == null) { throw new HttpResponseException(HttpStatusCode.NotFound); } return item; } //GET: /api/products?category=category public IEnumerable<Product> GetProductsByCategory(string category) { return repository.GetAll().Where(p=>string.Equals(p.Category,category,StringComparison.OrdinalIgnoreCase)); } //POST: /api/products public HttpResponseMessage PostProduct(Product item) { item = repository.Add(item); var response = Request.CreateResponse<Product>(HttpStatusCode.Created,item); string uri = Url.Link("DefaultApi", new { id=item.Id}); response.Headers.Location = new Uri(uri); return response; } //PUT: /api/products/id public void PutProduct(int id, Product product) { product.Id = id; if (!repository.Update(product)) { throw new HttpResponseException(HttpStatusCode.NotFound); } } //Delete: /api/products/id public void DeleteProduct(int id) { Product item = repository.Get(id); if (item == null) { throw new HttpResponseException(HttpStatusCode.NotFound); } repository.Remove(id); } } }
使該類繼承於ApiController類,在其中實現處理各類Get,Post,Put,Delete類型Http請求的方法。
每個方法前都有一句註釋,標識了該方法的針對的請求的類型(取決於方法的開頭),以及要請求到該方法,須要使用的url。
這些url是有規律的,見下圖:
api是必須的,products對應的是ProductsControllers控制器,而後又Http請求的類型和url的後邊地址決定。
這裏,咱們除了第三個「Get a product by category」,其餘方法都實現了。
7)最後,咱們來構建View視圖層,咱們更改Views文件夾中的Home文件夾下的Index.cshtml文件,這個文件是項目啓動頁,以下:
<div id="body"> <script src="~/Scripts/jquery-1.8.2.min.js"></script> <section > <h2>添加記錄</h2> Name:<input id="name" type="text" /><br /> Category:<input id="category" type="text" /> Price:<input id="price" type="text" /><br /> <input id="addItem" type="button" value="添加" /> </section> <section> <br /> <br /> <h2>修改記錄</h2> Id:<input id="id2" type="text" /><br /> Name:<input id="name2" type="text" /><br /> Category:<input id="category2" type="text" /> Price:<input id="price2" type="text" /><br /> <input id="showItem" type="button" value="查詢" /> <input id="editItem" type="button" value="修改" /> <input id="removeItem" type="button" value="刪除" /> </section> </div>
8)而後咱們給頁面添加js代碼,對應上面的按鈕事件,用來發起Http請求,以下:
<script> //用於保存用戶輸入數據 var Product = { create: function () { Id: ""; Name: ""; Category: ""; Price: ""; return Product; } } //添加一條記錄 請求類型:POST 請求url: /api/Products //請求到ProductsController.cs中的 public HttpResponseMessage PostProduct(Product item) 方法 $("#addItem").click(function () { var newProduct = Product.create(); newProduct.Name = $("#name").val(); newProduct.Category = $("#category").val(); newProduct.Price = $("#price").val(); $.ajax({ url: "/api/Products", type: "POST", contentType: "application/json; charset=utf-8", data: JSON.stringify(newProduct), success: function () { alert("添加成功!"); }, error: function (XMLHttpRequest, textStatus, errorThrown) { alert("請求失敗,消息:" + textStatus + " " + errorThrown); } }); }); //先根據Id查詢記錄 請求類型:GET 請求url: /api/Products/Id //請求到ProductsController.cs中的 public Product GetProduct(int id) 方法 $("#showItem").click(function () { var inputId = $("#id2").val(); $("#name2").val(""); $("#category2").val(""); $("#price2").val(""); $.ajax({ url: "/api/Products/" + inputId, type: "GET", contentType: "application/json; charset=urf-8", success: function (data) { $("#name2").val(data.Name); $("#category2").val(data.Category); $("#price2").val(data.Price); }, error: function (XMLHttpRequest, textStatus, errorThrown) { alert("請求失敗,消息:" + textStatus + " " + errorThrown); } }); }); //修改該Id的記錄 請求類型:PUT 請求url: /api/Products/Id //請求到ProductsController.cs中的 public void PutProduct(int id, Product product) 方法 $("#editItem").click(function () { var inputId = $("#id2").val(); var newProduct = Product.create(); newProduct.Name = $("#name2").val(); newProduct.Category = $("#category2").val(); newProduct.Price = $("#price2").val(); $.ajax({ url: "/api/Products/" + inputId, type: "PUT", data: JSON.stringify(newProduct), contentType: "application/json; charset=urf-8", success: function () { alert("修改爲功! "); }, error: function (XMLHttpRequest, textStatus, errorThrown) { alert("請求失敗,消息:" + textStatus + " " + errorThrown); } }); }); //刪除輸入Id的記錄 請求類型:DELETE 請求url: /api/Products/Id //請求到ProductsController.cs中的 public void DeleteProduct(int id) 方法 $("#removeItem").click(function () { var inputId = $("#id2").val(); $.ajax({ url: "/api/Products/" + inputId, type: "DELETE", contentType: "application/json; charset=uft-8", success: function (data) { alert("Id爲 " + inputId + " 的記錄刪除成功!"); }, error: function (XMLHttpRequest, textStatus, errorThrown) { alert("請求失敗,消息:" + textStatus + " " + errorThrown); } }); }); </script>
這裏,WebApi的一個簡單的增刪改查項目就完成了,選擇執行項目便可測試。注意到,其中用ajax發起請求時,發送到服務器端的數據直接是一個json字符串,固然這個json字符串中每一個字段要和Product.cs類中的每一個字段同名對應,在服務器端接收數據的時候,咱們並無對接收到的數據進行序列化,而返回數據給客戶端的時候也並無對數據進行反序列化,大大節省了之前開發中不停地進行序列化和反序列化的時間。