您现在的位置是:网站首页> 编程资料编程资料

使用ASP.Net WebAPI构建REST服务_实用技巧_

2023-05-24 369人已围观

简介 使用ASP.Net WebAPI构建REST服务_实用技巧_

一、创建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 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 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介绍得非常详细。

三、返回值

Asp.Net WebAPI服务函数的返回值主要可以分为void、普通对象、HttpResponseMessag、IHttpActionResult e四种,本文这里简单的介绍一下它们的区别。

1、返回void

返回void一般常用于Put和Delete函数。

public void Delete(int id) { }

当服务函数执行完成后,服务器端并不是啥都不干直接把客户端给断掉,而是发送一个标准的204 (No Content)的Http应答给客户端。

HTTP/1.1 204 No Content Cache-Control: no-cache Pragma: no-cache Expires: -1 Server: Microsoft-IIS/8.0 X-AspNet-Version: 4.0.30319 X-SourceFiles: =?UTF-8?B?Zjpc5paH5qGjXHZpc3VhbCBzdHVkaW8gMjAxM1xQcm9qZWN0c1xXZWJBcHBsaWNhdGlvbjFcV2ViQXBwbGljYXRpb24xXGFwaVx2YWx1ZXNcMQ==?= X-Powered-By: ASP.NET Date: Fri, 02 May 2014 13:32:07 GMT

2、返回普通对象

返回普通对象时,服务器将返回的对象序列化后(默认是json),通过Http应答返回给客户端。例如,

public class ValuesController : ApiController { public string Get() { return "hello"; } }

此时的返回结果是:

HTTP/1.1 200 OK Cache-Control: no-cache Pragma: no-cache Content-Type: application/json; charset=utf-8 Expires: -1 Server: Microsoft-IIS/8.0 X-AspNet-Version: 4.0.30319 X-SourceFiles: =?UTF-8?B?Zjpc5paH5qGjXHZpc3VhbCBzdHVkaW8gMjAxM1xQcm9qZWN0c1xXZWJBcHBsaWNhdGlvbjFcV2ViQXBwbGljYXRpb24xXGFwaVx2YWx1ZXM=?= X-Powered-By: ASP.NET Date: Fri, 02 May 2014 12:54:18 GMT Content-Length: 7 "hello"

异步返回普通对象:

WebAPI也是支持异步返回对象的:

 public async Task Get() { await Task.Delay(100); return "hello"; }

异步返回的时候,服务器异步等待函数执行完成后再将返回值返回给对象。由于这个过程对于客户端来说是透明的,这里就不列举报文了。

3、返回HttpResponseMessage

HttpResponseMessage是标准Http应答了,此时服务器并不做任何处理,直接将HttpResponseMessage发送给客户端。

public HttpResponseMessage Get() { var response = Request.CreateResponse(HttpStatusCode.OK); response.Content = new StringContent("hello", Encoding.UTF8); return response; }

此时的返回结果如下:

HTTP/1.1 200 OK Cache-Control: no-cache Pragma: no-cache Content-Length: 5 Content-Type: text/plain; charset=utf-8 Expires: -1 Server: Microsoft-IIS/8.0 X-AspNet-Version: 4.0.30319 X-SourceFiles: =?UTF-8?B?Zjpc5paH5qGjXHZpc3VhbCBzdHVkaW8gMjAxM1xQcm9qZWN0c1xXZWJBcHBsaWNhdGlvbjFcV2ViQXBwbGljYXRpb24xXGFwaVx2YWx1ZXM=?= X-Powered-By: ASP.NET Date: Fri, 02 May 2014 13:09:57 GMT hello

可以看到,这里返回的content-type仍然是原始定义的text类型,而不是json。要实现想上面的例子所示的结果,则需要将Get函数改写为如下形式

public HttpResponseMessage Get() { return Request.CreateResponse(HttpStatusCode.OK, "hello"); }

4、返回IHttpActionResult

IHttpActionResult是Web API 2 中引入的一个接口,它的定义如下:

public interface IHttpActionResult { Task ExecuteAsync
                
                

-六神源码网