在这篇文章中我们将讨论Web API设计、概念、功能,和对比Web API与WCF。
1. 实现一个Web API项目
我们从一个简单的实例开始讨论。我们使用
Visual Studio 2012做为开发环境。我们第一步是基于Web API模版创建一个ASP.NET MVC 4.0项目,如图1所示:
图1:基于Web API模板创建一个ASP.NET MVC 4项目
下一步,我们在model文件夹创建一个简单的数据模型。在解决方案资源文件夹中右键点击Model文件夹,选择
Add -> Class,如图2所示:
图2:添加新的数据模型
这只是一个教程,我定义一个产品数据模型,如表1所示。
public class Product
{
public int Id
{ get; set; }
public string Name
{ get; set; }
public string Category
{ get; set; }
public decimal Price
{ get; set; }}
表1: 定义产品模型
创建产品数据模型后,我们可以在Controllers文件夹中创建一个新的API控制器,用来处理产品数据模型。默认情况下,一个基于Web API模版的MVC项目可以添加两个控制器: 一个继承于Controller类,另一个继承于ApiController类。在解决方案资源文件夹中右击Controllers文件夹,在弹出窗口中选择“Empty API controller”,添加一个新的controller。如图3所示:
图3:添加Empty API controller
Controller代码如表2所示:
public class ProductsController : ApiController
{
List products = new List();
public IEnumerable GetAllProducts()
{
GetProducts();
return products;
}
private void GetProducts()
{
products.Add(new Product {Id = 1, Name = "Television", Category="Electronic", Price=82000});
products.Add(new Product { Id = 2, Name = "Refrigerator", Category = "Electronic", Price = 23000 });
products.Add(new Product { Id = 3, Name = "Mobiles", Category = "Electronic", Price = 20000 });
products.Add(new Product { Id = 4, Name = "Laptops", Category = "Electronic", Price = 45000 });
products.Add(new Product { Id = 5, Name = "iPads", Category = "Electronic", Price = 67000 });
products.Add(new Product { Id = 6, Name = "Toys", Category = "Gift Items", Price = 15000 });
}
public IEnumerable GetProducts(int selectedId)
{
if (products.Count() > 0)
{
return products.Where(p => p.Id == selectedId);
}
else
{
GetProducts();
return products.Where(p => p.Id == selectedId);
}
}
表2:添加ApiController类到实例项目
运行项目并连接到API,通过“/api/Products”,例如: http://localhost:8747/api/Products 。你也可以传递
SelectedId
参数去调用GetProducts方法,例如:
http://localhost:8747/api/Products?SelectedId=2
2. 传递复杂的对象给Web API的方法
在Web API中传递一个简单的对象是容易的,但是大部分情况下,你需要传递一个复杂的对象参数。你可以通过[FromUrl]或[FromBody]属性来传递对象。[FromBody]属性从request body里面读取数据。但是,这个属性在方法的参数列表中只能使用一次。
让我们用代码段去解释使用复杂参数的重要性,如表3所示:
public class SampleController : ApiController
{
///
/// Get time
///
///
///
public string GetTime(Time t)
{
return string.Format("Received Time: {0}:{1}.{2}", t.Hour, t.Minute, t.Second);
}
}
public class Time
{
public int Hour { get; set; }
public int Minute { get; set; }
public int Second { get; set; }
}
表3:
给方法
传递复杂的参数
现在,让我们使用Hour,Minute和Second参数给GetTime方法传值。你可以看见它出错了,返回空引用错误。如图4所示:
图4:当调用GetTime方法时出错了
虽然我们已经意识到输入值需要关联到Time对象,但是API方法不能
正确地
映射输入值与对象属性。现在我们看看,是否修改代码去包含[FromUri]属性能够处理URL查询字符串里的复杂对象。下面的片段中我们在Time对象前申明了[FromUri]属性:
public string GetTime([FromUri] Time t)
{ -------------------}
现在我们通过这个方法,传递相同的值,将会有不同的结果,如图5所示:
图5:调用GetTime方法成功
3. 使用HttpClient API
HttpClient是一个可扩展API,可以通过Http方式访问任何服务或网站。这个HttpClient被引进到WCF Web API, 而且现在
.NET Framework 4.5中的
ASP.NET Web API也有了这个功能。你可以在后台和services(例如:WCF)中使用HttpClient去访问Web API方法。
这个代码段创建了一个HttpClient对象并且异步访问实例中的API方法。
// asynchronous accessing of web api method
async Task GetData()
{
StringBuilder result = new StringBuilder();
// Define the httpClient object using (HttpClient client = new HttpClient())
{
// Define the base address of the MVC application hosting the web api
// accessing the web api from the same solution
client.BaseAddress = new Uri(HttpContext.Current.Request.Url.AbsoluteUri);
// Define the serialization used json/xml/ etc
client.DefaultRequestHeaders.Accept.Add(
new MediaTypeWithQualityHeaderValue("application/json"));
// Call the method
HttpResponseMessage response = client.GetAsync("api/products").Result;
if (response.IsSuccessStatusCode)
{
// Convert the result into business object
var products = response.Content.ReadAsAsync>().Result;
foreach (var p in products)
{
result.Append(string.Format("{0} --- [Price: {1} Category: {2}] ", p.Name, p.Price, p.Category));
}
}
else
{
result.Append(string.Format("Error Code:-{0} Error Details: {1}", (int)response.StatusCode, response.ReasonPhrase));
}
}
data.Text = result.ToString();
}
表4:创建一个HttpClient对象去访问实例中的API方法
4. 用jQuery访问Web API
在Html5 Web应用中,你可以使用jQuery直接访问Web API。你可以使用getJSON()方法调用API得到结果,然后取出业务对象。jQuery能识别内部字段关联的业务对像,例如:data[i].Price。
这个代码段演示了从Product API方法查找数据并显示数据到一个表格。