HTTP不僅僅服務(wù)于web頁面,同時也是構(gòu)建暴露服務(wù)和數(shù)據(jù)的API的強大平臺。HTTP有著簡單、靈活和無處不在的特點。你能想到的幾乎所有平臺都包含有一個HTTP庫,所以HTTP服務(wù)可以遍及廣泛的客戶端,包括瀏覽器、移動設(shè)備和傳統(tǒng)桌面應(yīng)用程序。
ASP.NET Web API是一個在.NET框架上構(gòu)建web API的框架。在本教程中,你將使用ASP.NET Web API來創(chuàng)建一個返回產(chǎn)品列表的web API。
在本教程中,你將使用ASP.NET Web API來創(chuàng)建一個返回產(chǎn)品列表的web API。前端頁面使用jQuery來顯示結(jié)果。
開啟Visual Studio并在開始頁面選擇New Project?;蛘咴贔ile目錄下選擇New,然后選擇Project。
在Template面板中,選擇Installed Templates,然后展開Visual C#節(jié)點。在Visual C#節(jié)點下,選擇Web。在項目模板列表中,選擇ASP.NET Web Application。命名項目為“ProductsApp”并點擊OK。
在NEW ASP.NET Project對話框中,選擇Empty模板。在”Add folders and core references for”,選中Web API。點擊OK。
注釋:你也可以用“Web API”模板來創(chuàng)建Web API。Web API模板使用了ASP.NET MVC來提供API的幫助頁面。我在本教程中使用Empty模板是因為我希望不用MVC來展示W(wǎng)eb API。通常,你不必了解ASP.NET MVC就能使用Web API。
模型是在你的應(yīng)用程序中表示數(shù)據(jù)的對象。ASP.NET Web API能夠?qū)⒛愕哪P妥詣有蛄谢蒍SON、XML或其他格式,然后將其序列化數(shù)據(jù)寫入到HTTP響應(yīng)消息的body中。只要客戶端能夠讀取序列化格式,它就能夠反序列化出對象。幾乎所有客戶端都能解析XML或JSON。而且,客戶端還能通過在HTTP請求的Accept header中設(shè)置來指明它想要的格式。
讓我們來創(chuàng)建一個表示產(chǎn)品的簡單模型吧。
如果Solution Explorer沒有顯示出來,點擊View菜單,然后選擇Solution Explorer。在Solution Explorer中,右擊Models文件夾。從上下文菜單中選擇Add,然后選擇Class。
命名該類為“Product”。添加以下屬性到Product類中。
namespace ProductsApp.Models
{
public class Product
{
public int Id { get; set; }
public string Name { get; set; }
public string Category { get; set; }
public decimal Price { get; set; }
}
}
在Web API中,控制器(controller)是處理HTTP請求的對象。我們將添加一個能夠根據(jù)ID來返回多個或一個產(chǎn)品的控制器。
備注:如果你還沒有使用過ASP.NET MVC,你應(yīng)該已經(jīng)對控制器很熟悉了。Web API的控制器和MVC的控制器很相近,但是它繼承的是ApiController而不是Controller。
在Solution Explorer中,右擊Controllers文件夾。選擇Add,然后選擇Controller。
在Add Scaffold對話框中,選擇Web API Controller – Empty。點擊Add。
在Add Controller對話框,給控制器命名為”ProductsController”。點擊Add。
接下來便會在Controllers文件夾下創(chuàng)建一個名為ProductsController.cs的文件。
備注:其實你不必非得把控制器添加到Controllers文件夾下。文件夾名稱只是為了更方便你組織源文件。
如果文件沒有打開,那就雙擊文件打開它。在文件中替換成以下代碼:
using ProductsApp.Models;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Web.Http;
namespace ProductsApp.Controllers
{
public class ProductsController : ApiController
{
Product[] products = new Product[]
{
new Product { Id = 1, Name = "Tomato Soup", Category = "Groceries", Price = 1 },
new Product { Id = 2, Name = "Yo-yo", Category = "Toys", Price = 3.75M },
new Product { Id = 3, Name = "Hammer", Category = "Hardware", Price = 16.99M }
};
public IEnumerable<Product> GetAllProducts()
{
return products;
}
public IHttpActionResult GetProduct(int id)
{
var product = products.FirstOrDefault((p) => p.Id == id);
if (product == null)
{
return NotFound();
}
return Ok(product);
}
}
}
為了讓示例簡單化,products被存儲在控制器類中的固定數(shù)組中。當然,在實際應(yīng)用程序中,你可能想要查詢數(shù)據(jù)庫或使用其他外部數(shù)據(jù)源。
控制器定義了兩個返回產(chǎn)品的方法:
沒錯,你已經(jīng)有一個可以使用的web API了。控制器上的每個方法都對應(yīng)一個或多個URI:
| Controlle Method | URI |
|---|---|
| GetAllProducts | /api/products |
| GetProduct | /api/products/id |
對于GetProduct方法,URI中的id是一個占位符。例如,為了得到一個ID為5的產(chǎn)品,URI是api/products/5。
在本節(jié)中,我們將添加一個使用AJAX來調(diào)用Web API的HTML頁面。我們將使用jQuery來產(chǎn)生AJAX調(diào)用并用返回結(jié)果來更新頁面。
在Solution Explorer中,右擊項目并選擇Add,然后選擇New Item。
在Add New Item對話框中,選擇Visual C#下的Web節(jié)點,然后選擇HTML Page選項。命名頁面為“index.html”。
用以下代碼替換文件中的全部:
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>Product App</title>
</head>
<body>
<div>
<h2>All Products</h2>
<ul id="products" />
</div>
<div>
<h2>Search by ID</h2>
<input type="text" id="prodId" size="5" />
<input type="button" value="Search" onclick="find();" />
<p id="product" />
</div>
<script src="http://ajax.aspnetcdn.com/ajax/jQuery/jquery-2.0.3.min.js"></script>
<script>
var uri = 'api/products';
$(document).ready(function () {
// Send an AJAX request
$.getJSON(uri)
.done(function (data) {
// On success, 'data' contains a list of products.
$.each(data, function (key, item) {
// Add a list item for the product.
$('<li>', { text: formatItem(item) }).appendTo($('#products'));
});
});
});
function formatItem(item) {
return item.Name + ': $' + item.Price;
}
function find() {
var id = $('#prodId').val();
$.getJSON(uri + '/' + id)
.done(function (data) {
$('#product').text(formatItem(data));
})
.fail(function (jqXHR, textStatus, err) {
$('#product').text('Error: ' + err);
});
}
</script>
</body>
</html>
有好幾個方法去得到j(luò)Query。在本例中,我使用Microsoft Ajax CDN。你也可以在http://jquery.com/下載它,讓ASP.NET “Web API”項目包含jQuery。
為了得到Products列表,可以發(fā)送一個HTTP的GET請求到“/api/products”。
jQuery的getJSON函數(shù)會發(fā)送AJAX請求。其中包含了JSON對象數(shù)組。done函數(shù)指定了一個當請求成功時觸發(fā)的回調(diào)。在回調(diào)中,我們用產(chǎn)品信息更新DOM。
$(document).ready(function () {
// Send an AJAX request
$.getJSON(apiUrl)
.done(function (data) {
// On success, 'data' contains a list of products.
$.each(data, function (key, item) {
// Add a list item for the product.
$('<li>', { text: formatItem(item) }).appendTo($('#products'));
});
});
});
如果想要通過ID來取得產(chǎn)品,可以發(fā)送HTTP的GET請求到”/api/products/id“,其中id就是產(chǎn)品的ID。
function find() {
var id = $('#prodId').val();
$.getJSON(apiUrl + '/' + id)
.done(function (data) {
$('#product').text(formatItem(data));
})
.fail(function (jqXHR, textStatus, err) {
$('#product').text('Error: ' + err);
});
}
我們?nèi)匀皇褂胓etJSON來發(fā)送AJAX請求,但是這次我們將ID放到URI請求中。它的響應(yīng)會是一個代表了單個產(chǎn)品的JSON對象。
按F5開始調(diào)試應(yīng)用程序,web頁面看起來會是下面這樣:
為了通過ID獲得產(chǎn)品,輸入ID并點擊Search。
如果你輸入了一個無效的ID,那么服務(wù)器就會返回HTTP錯誤消息。
當你工作于HTTP服務(wù)時,如果能夠查看HTTP請求和響應(yīng)的詳細無疑是非常有幫助的。你可以在IE9中使用F12開發(fā)者工具來做這些操作。在IE9中,按F12來打開工具。點擊Network面板,并點擊Start Capturing。現(xiàn)在返回到web頁面,并按F5來重新加載web頁面。IE將會捕捉到瀏覽器和web服務(wù)器之間的HTTP傳輸。下圖顯示了一個頁面的所有HTTP傳輸。
定位到相對URI”api/products/“。選中并點擊Go to detailed view。在詳細視圖中,這里多個面板用于查看請求和響應(yīng)的header和body。
例如,如果你點擊Request headers,你就會看到客戶端在Accept header請求了”application/json“。
如果你點擊了Response body,你就會看到產(chǎn)品列表如何被序列化成JSON。其他瀏覽器也有相似的功能。另一個有用的工具是Fiddler,它是一個web調(diào)試代理工具。你可以使用Fiddler來查看HTTP傳輸,也可以合成HTTP請求,后者能夠給予你在請求上對于HTTP頭部的完全控制。