zoukankan      html  css  js  c++  java
  • Web API 2中的Action Results

    [译]Action Results in Web API 2

    单击此处查看原文

    本文阐述了ASP.NET Web API是如何将controller action的返回值转换为HTTP response message的。

    一个Web API controller action可以有以下几种返回值:

    1. void
    2. HttpResponseMessage
    3. IHttpActionResult
    4. Some other type(其他)

    根据以上四种返回类型的不同,Web API会使用不同的机制创建HTTP response。

    返回类型 创建方式
    void 无内容
    HttpResponseMessage 直接转换为Http response message
    IHttpActionResult 调用ExecuteAsync来创建一个HttpResponseMessage,然后转换为Http response message
    Other Type 将序列化的返回值写入response body;返回 状态码200(OK)

    本文的其余部分将阐述以上四种情况的详细内容。

    void

    如果返回类型是void,Web API会直接返回一个空的HTTP response,状态码:200,表示无内容。

    示例controller:

    public class ValuesController : ApiController
    {
        public void Post()
        {
        }
    }
    

    HTTP response:

    HTTP/1.1 204 No Content
    Server: Microsoft-IIS/8.0
    Date: Mon, 27 Jan 2014 02:13:26 GMT
    

    HttpResponseMessage

    如果action返回了一个HttpResponseMessage,Web API会将该返回值转换为一个HTTP response message,使用HttpResponseMessage对象的属性来填充这个HTTP response message。

    下面的示例代码中对一个response message 进行了大量的控制。比如:它设置了Cache-Control header。

    public class ValuesController : ApiController
    {
        public HttpResponseMessage Get()
        {
            HttpResponseMessage response = Request.CreateResponse(HttpStatusCode.OK, "value");
            response.Content = new StringContent("hello", Encoding.Unicode);
            response.Headers.CacheControl = new CacheControlHeaderValue()
            {
                MaxAge = TimeSpan.FromMinutes(20)
            };
            return response;
        } 
    }
    

    响应:

     HTTP/1.1 200 OK
    Cache-Control: max-age=1200
    Content-Length: 10
    Content-Type: text/plain; charset=utf-16
    Server: Microsoft-IIS/8.0
    Date: Mon, 27 Jan 2014 08:53:35 GMT
    
    hello
    

    如果你通过使用一个domain model(领域模型)来使用CreateResponse方法,Web API使用media formatter来将序列化的模型写入response body。

    public HttpResponseMessage Get()
    {
        // Get a list of products from a database.
        IEnumerable<Product> products = GetProductsFromDB();
    
        // Write the list to the response body.
        HttpResponseMessage response = Request.CreateResponse(HttpStatusCode.OK, products);
        return response;
    }
    

    Web API在请求中使用Accept header来选择formatter。更多详情,参见Content Negotiation

    IHttpActionResult

    IHttpActionResult接口在Web API 2中有过相关介绍。它主要定义了一个**HttpResponseMessage **factory。使用此接口有以下的几点优势:

    • 简化了你对controllers进行的unit test
    • 将创建Http responses的通用逻辑分离到独立的类中
    • 通过隐藏构建response的底层实现细节,使得controller action的功能简介明了

    IHttpActionResult声明了一个方法:ExecuteAsync,用于异步创建HttpResponseMessage实例。

    public interface IHttpActionResult
    {
        Task<HttpResponseMessage> ExecuteAsync(CancellationToken cancellationToken);
    }
    

    如果一个controller action返回一个IHttpActionResult,Web API 将调用ExecuteAsync方法来创建一个HttpResponseMessage。然后它再将HttpResponseMessage转换为一个HTTP response message。
    以下是一个IHttpActionResult接口的简单实现,它会创建一个纯文本的响应。

    public class TextResult : IHttpActionResult
    {
        string _value;
        HttpRequestMessage _request;
    
        public TextResult(string value, HttpRequestMessage request)
        {
            _value = value;
            _request = request;
        }
        public Task<HttpResponseMessage> ExecuteAsync(CancellationToken cancellationToken)
        {
            var response = new HttpResponseMessage()
            {
                Content = new StringContent(_value),
                RequestMessage = _request
            };
            return Task.FromResult(response);
        }
    }
    

    controller action:

    public class ValuesController : ApiController
    {
        public IHttpActionResult Get()
        {
            return new TextResult("hello", Request);
        }
    }
    

    response:

    HTTP/1.1 200 OK
    Content-Length: 5
    Content-Type: text/plain; charset=utf-8
    Server: Microsoft-IIS/8.0
    Date: Mon, 27 Jan 2014 08:53:35 GMT
    
    hello
    

    通常你需要将IHttpActionResult的实现写在System.Web.Http.Results命名空间下。因为ApiController定义的helper method会返回这些内置的action results。

    下面的示例中,如果一个请求没有匹配到现有的product ID,这个controller将调用ApiController.NotFound来创建一个404(Not Found) response。否则,controller将调用ApiController.OK,来创建一个200(OK) response,它包含了product信息。

    public IHttpActionResult Get (int id)
    {
        Product product = _repository.Get (id);
        if (product == null)
        {
            return NotFound(); // Returns a NotFoundResult
        }
        return Ok(product);  // Returns an OkNegotiatedContentResult
    }
    

    Other Return Type

    如果返回类型是其他任何的一种形式,Web API使用了一个media formatter来序列化这些返回值,然后将这些序列化的值写入response body。这个response status code是200(ok)。

    public class ProductsController : ApiController
    {
        public IEnumerable<Product> Get()
        {
            return GetAllProductsFromDB();
        }
    }
    

    使用这种方法的缺点是,你无法直接返回一个error code,比如404。不过你可以抛出一个HttpResponseException异常来替代error code。更多详情,参见Exception Handling in ASP.NET Web API

    Web API在请求中使用Accept header来选择formatter。更多详情,参见Content Negotiation

    示例请求:

    GET http://localhost/api/products HTTP/1.1
    User-Agent: Fiddler
    Host: localhost:24127
    Accept: application/json
    

    示例响应:

    HTTP/1.1 200 OK
    Content-Type: application/json; charset=utf-8
    Server: Microsoft-IIS/8.0
    Date: Mon, 27 Jan 2014 08:53:35 GMT
    Content-Length: 56
    
    [{"Id":1,"Name":"Yo-yo","Category":"Toys","Price":6.95}]
    
  • 相关阅读:
    golang闭包,传统斐波那契
    ubuntu 软件桌面图标创建
    Mysql系列-性能优化神器EXPLAIN使用介绍及分析
    Sklearn-GridSearchCV网格搜索
    sklearn逻辑回归(Logistic Regression)类库总结
    scikit-learn模块学习笔记(数据预处理模块preprocessing)
    Python中的高级数据结构
    Python进阶之“属性(property)”详解
    python模块之itertools
    python list有关remove的问题
  • 原文地址:https://www.cnblogs.com/JoiT/p/6275463.html
Copyright © 2011-2022 走看看