一、创建WebAPI应用程序
1、Web API 1版本
首先创建一个Asp.Net MVC 4 Web应用程序(我这里用的是Visual Studio 2012)。
在出来的模板中选择Web API。点击确定后,就创建了一个空的WebAPI服务。
2、 Web API 2版本
点击确定后,就创建了一个空的WebAPI服务。此时只有一个空项目,还没有任何功能
在进行下一步之前,首先我们来看一下REST的基本操作模型,大致可以分为如下四种:
- POST — 创建资源
- GET — 检索资源
- PUT — 更新资源
- DELETE — 删除资源
非常经典的CRUD模型。
在Web API中实现这样一个的模型是非常简单的,直接使用向导建一个Controller即可
在Web API中生成默认的ValuesController
默认的模板内容如下:
public class ValuesController : ApiController { // GET api/values public IEnumerable<string> Get() { return new string[] { "value1", "value2" }; } // GET api/values/5 public string Get(int id) { return "value"; } // POST api/values public void Post([FromBody]string value) { } // PUT api/values/5 public void Put(int id, [FromBody]string value) { } // DELETE api/values/5 public void Delete(int id) { } }
这其实已经帮我们实现了一个最基本的服务了,不过这个服务中只实现了Get,它支持如下两种中方式的URL访问(其它的方式也能访问,但没有具体的效果):
api/values 访问所有的Value列表
api/values/{id} 根据ID访问Value
按Ctrl + F5中执行,在浏览器中输入相应的地址即可看到结果
下面我们要做的就是完善它,实现一个简单的查询功能,这里我引用了微软官方的一个例子:
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> Get() { return products; } public IHttpActionResult Get(int id) { var product = products.FirstOrDefault((p) => p.Id == id); if (product == null) { return NotFound(); } return Ok(product); } } public class Product { public int Id { get; set; } public string Name { get; set; } public string Category { get; set; } public decimal Price { get; set; } }
此时,我们就可以在浏览器中看到结果了(由于Controller改名字了,此时的地址就变成了api/products)
到此为止,一个基于Asp.net Web API的 简单的REST Web服务就构建完成了,由于篇幅所限,这里就不做更多的介绍了,跟多信息可以参看微软官方文档:Getting Started with ASP.NET Web API 2。
备注:WebAPI升级到 WebAPI 2如下命令更新web Api:
Install-Package Microsoft.AspNet.WebApi
二、路由
REST并没有像传统的RPC服务那样显式指定了服务器函数的访问路径,而是将URL根据一定的规则映射为服务函数入口,这个规则就称之为路由。Asp.Net WebAPI的路由方式和Asp.Net MVC是相同的,它支持两种路由方式,传统的路由映射和特性路由。 路由规则WebApiConfig.cs中定义。
它的默认内容如下:
public static class WebApiConfig { public static void Register(HttpConfiguration config) { // Web API configuration and services // Web API routes config.MapHttpAttributeRoutes(); config.Routes.MapHttpRoute( name: "DefaultApi", routeTemplate: "api/{controller}/{id}", defaults: new { id = RouteParameter.Optional } ); } }
它默认注册了两种路由规则,第一行注册的是特性路由,第二行注册的则是传统的映射路由。默认情况下,由于我们没有编写特性路由规则,则是按照传统的Controller方式映射路由。
关于路由规则,MSDN文档ASP.NET 路由介绍得非常详细,但由于其介绍得太详细了,反而不容易得其门而入,这里我只拿默认的路由规则来简单但的介绍一下我的理解,它的uri格式是这样的"api/{controller}/{id}",其中id是可选的。拿前文的例子来说吧,
- 当我们对api/products地址进行访问的时候,系统则会首先找到名为ProductsController的控制器。
- 然后,根据访问方式查找函数,由于这里是Get操作,则查找Get开头的函数, 这里会找到Get()和Get(int id)两个重载版本。
- 最后,根据参数来匹配具体的函数,因为这里没有带参数id。因此匹配到了Get()函数,返回了所有的集合。
另外,这里也有几个常用的衍生规则:
- 根据操作方式找函数的时候,只需要匹配首部即可,因此我们编写函数的时候写成Get()和GetProduct()都是可以的。,
- 根据操作方式找函数的时候查找的时候不分大小写,因此写成Get()或get()都是可以的
当我们使用带参数的版本时候,也有几个需要注意的地方:
- 参数名不分大小写,我们写成id或ID都是可以的
- 参数名要求严格匹配的,我们写成ID2是不行的,此时则会匹配到错误的结果Get()
默认的规则虽然大多数的时候还是比较方便的,但是很多时候我们需要手动指定个性化的路由规则。例如,我们可以自定义一个按名称来查询的url:api/products/name=xxx。这个时候则可以用特性路由快速的实现了:
[Route("api/{controller}/name={name}")] public IHttpActionResult GetByName(string name)
关于特性路由,MSDN原文Attribute Routing in ASP.NET MVC 5介绍得非常详细,国内也有非常不错的译文版本Attribute Routing in ASP.NET MVC 5 翻译及补充,这里就不做多少介绍了。