• Action Results in Web API 2


    https://docs.microsoft.com/en-us/aspnet/web-api/overview/getting-started-with-aspnet-web-api/action-results

    This topic describes how ASP.NET Web API converts the return value from a controller action into an HTTP response message.

    A Web API controller action can return any of the following:

    1. void
    2. HttpResponseMessage
    3. IHttpActionResult
    4. Some other type

    Depending on which of these is returned, Web API uses a different mechanism to create the HTTP response.

    Return typeHow Web API creates the response
    void Return empty 204 (No Content)
    HttpResponseMessage Convert directly to an HTTP response message.
    IHttpActionResult Call ExecuteAsync to create an HttpResponseMessage, then convert to an HTTP response message.
    Other type Write the serialized return value into the response body; return 200 (OK).

    The rest of this topic describes each option in more detail.

    void

    If the return type is void, Web API simply returns an empty HTTP response with status code 204 (No Content).

    Example controller:

      public class ValuesController : ApiController
        {
            [HttpGet]
            public void Post()
            {
            }
        }

    request

    GET http://localhost/Chuck_WebApi/api/values/post HTTP/1.1
    User-Agent: Fiddler
    Host: localhost
    Content-Length: 0

    response

    HTTP/1.1 204 No Content
    Cache-Control: no-cache
    Pragma: no-cache
    Expires: -1
    Server: Microsoft-IIS/10.0
    X-AspNet-Version: 4.0.30319
    X-Powered-By: ASP.NET
    Date: Thu, 17 Jan 2019 10:04:57 GMT

    HttpResponseMessage

    If the action returns an HttpResponseMessage, Web API converts the return value directly into an HTTP response message, using the properties of the HttpResponseMessage object to populate the response.

    This option gives you a lot of control over the response message. For example, the following controller action sets the Cache-Control header.

    需要把路由从默认的routeTemplate: "api/{controller}/{id}"调整为routeTemplate: "api/{controller}/{action}/{id}"

      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;
            }

    request

    GET http://localhost/Chuck_WebApi/api/values/get HTTP/1.1
    User-Agent: Fiddler
    Host: localhost
    Content-Length: 0

    response

    HTTP/1.1 200 OK
    Cache-Control: max-age=1200
    Content-Length: 10
    Content-Type: text/plain; charset=utf-16
    Server: Microsoft-IIS/10.0
    X-AspNet-Version: 4.0.30319
    X-Powered-By: ASP.NET
    Date: Thu, 17 Jan 2019 10:25:14 GMT

    hello

    If you pass a domain model to the CreateResponse method, Web API uses a media formatter to write the serialized model into the response body.

    https://docs.microsoft.com/en-us/aspnet/web-api/overview/advanced/dependency-injection

    https://autofaccn.readthedocs.io/en/latest/integration/webapi.html

     此处代码的前提是,在项目启动的时候,使用了Autofac.WebApi2初始化GlobalConfiguration.Configuration.DependencyResolver

     public HttpResponseMessage Get2()
            {
                var dependencyResolver = GlobalConfiguration.Configuration.DependencyResolver;
                var controller = dependencyResolver.GetService(typeof(ProductsController));
                ProductsController productsController = controller as ProductsController;
                //productsController.ControllerContext //might need set value here
    
                // Get a list of products from a database.
                IEnumerable<Product> products = productsController.GetAllProducts();
    
                // Write the list to the response body.
                HttpResponseMessage response = Request.CreateResponse(HttpStatusCode.OK, products);
                return response;
            }

    Web API uses the Accept header in the request to choose the formatter. For more information, see Content Negotiation.

    request

    GET http://localhost/Chuck_WebApi/api/values/get2 HTTP/1.1
    User-Agent: Fiddler
    Host: localhost
    Content-Length: 0

    response

    HTTP/1.1 200 OK
    Cache-Control: no-cache
    Pragma: no-cache
    Content-Type: application/json; charset=utf-8
    Expires: -1
    Server: Microsoft-IIS/10.0
    X-AspNet-Version: 4.0.30319
    X-Powered-By: ASP.NET
    Date: Thu, 17 Jan 2019 11:13:15 GMT
    Content-Length: 182

    [{"Id":1,"Name":"Tomato Soup","Category":"Groceries","Price":1.0},{"Id":2,"Name":"Yo-yo","Category":"Toys","Price":3.75},{"Id":3,"Name":"Hammer","Category":"Hardware","Price":16.99}]

    IHttpActionResult

    The IHttpActionResult interface was introduced in Web API 2. Essentially, it defines an HttpResponseMessage factory. Here are some advantages of using the IHttpActionResult interface:

    • Simplifies unit testing your controllers.
    • Moves common logic for creating HTTP responses into separate classes.
    • Makes the intent of the controller action clearer, by hiding the low-level details of constructing the response.

    IHttpActionResult contains a single method, ExecuteAsync, which asynchronously creates an HttpResponseMessage instance.

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

    If a controller action returns an IHttpActionResult, Web API calls the ExecuteAsync method to create an HttpResponseMessage. Then it converts the HttpResponseMessage into an HTTP response message.

    Here is a simple implementaton of IHttpActionResult that creates a plain text response:

    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);
            }
        }

    Example controller action:

     public IHttpActionResult Get3()
            {
                return new TextResult("hello", Request);
            }

    request

    GET http://localhost/Chuck_WebApi/api/values/get3 HTTP/1.1
    User-Agent: Fiddler
    Host: localhost
    Content-Length: 0

    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/10.0
    X-AspNet-Version: 4.0.30319
    X-Powered-By: ASP.NET
    Date: Fri, 18 Jan 2019 02:19:02 GMT

    hello

    More often, you will use the IHttpActionResult implementations defined in the System.Web.Http.Results namespace. The ApiController class defines helper methods that return these built-in action results.

    https://docs.microsoft.com/en-us/previous-versions/aspnet/dn314678(v=vs.118)    系统内定的一些IHttpActionResult 的实现

    ApiController 本身也内置了一部分的方法,来返回对应的实现

    BadRequestErrorMessageResult

    UnauthorizedResult

    In the following example, if the request does not match an existing product ID, the controller calls ApiController.NotFound to create a 404 (Not Found) response.

    Otherwise, the controller calls ApiController.OK, which creates a 200 (OK) response that contains the product.

    public IHttpActionResult Get4(int id)
            {
                var product = products.FirstOrDefault((p) => p.Id == id);
                if (product == null)
                {
                    return NotFound(); // Returns a NotFoundResult
                }
                return Ok(product);  // Returns an OkNegotiatedContentResult
            }

    request1

    GET http://localhost/Chuck_WebApi/api/values/get4/3 HTTP/1.1
    User-Agent: Fiddler
    Host: localhost
    Content-Length: 0

    response1

    HTTP/1.1 200 OK
    Cache-Control: no-cache
    Pragma: no-cache
    Content-Type: application/json; charset=utf-8
    Expires: -1
    Server: Microsoft-IIS/10.0
    X-AspNet-Version: 4.0.30319
    X-Powered-By: ASP.NET
    Date: Fri, 18 Jan 2019 02:36:31 GMT
    Content-Length: 60

    {"Id":3,"Name":"Hammer","Category":"Hardware","Price":16.99}

    request2

    GET http://localhost/Chuck_WebApi/api/values/get4/4 HTTP/1.1
    User-Agent: Fiddler
    Host: localhost
    Content-Length: 0

    response2

    HTTP/1.1 404 Not Found
    Cache-Control: no-cache
    Pragma: no-cache
    Expires: -1
    Server: Microsoft-IIS/10.0
    X-AspNet-Version: 4.0.30319
    X-Powered-By: ASP.NET
    Date: Fri, 18 Jan 2019 02:50:06 GMT
    Content-Length: 0

    Other Return Types

    For all other return types, Web API uses a media formatter to serialize the return value.

    Web API writes the serialized value into the response body.

    The response status code is 200 (OK).

    public IEnumerable<Product> GetAllProducts()
            {
                return products;
            }

    A disadvantage of this approach is that you cannot directly return an error code, such as 404.

    However, you can throw an HttpResponseException for error codes.

    For more information, see Exception Handling in ASP.NET Web API.

    Web API uses the Accept header in the request to choose the formatter. For more information, see Content Negotiation.

    request

    GET http://localhost/Chuck_WebApi/api/products/getallproducts HTTP/1.1
    User-Agent: Fiddler
    Host: localhost
    Content-Length: 0

    response

    HTTP/1.1 200 OK
    Cache-Control: no-cache
    Pragma: no-cache
    Content-Type: application/json; charset=utf-8
    Expires: -1
    Server: Microsoft-IIS/10.0
    X-AspNet-Version: 4.0.30319
    X-Powered-By: ASP.NET
    Date: Fri, 18 Jan 2019 03:10:56 GMT
    Content-Length: 182

    [{"Id":1,"Name":"Tomato Soup","Category":"Groceries","Price":1.0},{"Id":2,"Name":"Yo-yo","Category":"Toys","Price":3.75},{"Id":3,"Name":"Hammer","Category":"Hardware","Price":16.99}]

     

  • 相关阅读:
    [LeetCode每日1题][简单] 169. 多数元素
    [LeetCode每日1题][简单] 1013. 将数组分成和相等的三个部分
    [LeetCode每日1题][中等] 322. 零钱兑换
    [LeetCode每日1题][中等] 面试题59
    软工实践个人总结
    2019 SDN大作业
    2019 SDN上机第7次作业
    第01组 Beta版本演示
    如果有一天我变得很有钱组——alpha冲刺day7
    如果有一天我变得很有钱组——alpha冲刺day6
  • 原文地址:https://www.cnblogs.com/chucklu/p/10283937.html
Copyright © 2020-2023  润新知