ASP.NET Web API 2 的返回结果

Posted xgzh

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了ASP.NET Web API 2 的返回结果相关的知识,希望对你有一定的参考价值。

  1. HttpResponseMessage
  2. IHttpActionResult
  3. void
  4. 某些其他类型
  5. 总结归纳

HttpResponseMessage


????HttpResponseMessage是ASP.NET Web API 的标准返回值可以直接将转换为 HTTP 响应消息,那为什么我们不推荐使用HttpResponseMessage,主要是因为用起来比较麻烦,当然HttpResponseMessage提供大量控制的响应消息用来操作设置的缓存控制标头。为什么说HttpResponseMessage是ASP.NET Web API 的标准返回值,最后再讲,先看看如何使用HttpResponseMessage作为返回值。

    public HttpResponseMessage Get()
    
        HttpResponseMessage response = Request.CreateResponse(HttpStatusCode.Accepted, "value");
        //设置内容和编码
        response.Content = new StringContent("Link sucess", Encoding.BigEndianUnicode); 
        response.Headers.CacheControl = new CacheControlHeaderValue()
        
            MaxAge = TimeSpan.FromMinutes(10),//设置缓存

        ;
        return response;
    

????HTTP 响应:

    HTTP/1.1 202 Accepted
    Cache-Control: max-age=1200
    Content-Length: 22
    Content-Type: text/plain; charset=utf-16
    Server: Microsoft-IIS/10.0
    X-AspNet-Version: 4.0.30319
    X-SourceFiles: =?UTF-8?B?RTpcZ2l0SHViXFdlYkFQSVN0dWR5QXBwbGljYXRpb25cV2ViQVBJU3R1ZHlBcHBsaWNhdGlvblxhcGlcUmV0dXJuVmFsdWU=?=
    X-Powered-By: ASP.NET

????HttpResponseMessage作为返回值使用的太少,我除了下载文件外基本没用到过,

    public HttpResponseMessage DownloadFile(string filename)
    
     
            string filePath = HttpContext.Current.Server.MapPath("/") + "Files\\" + filename;
            FileStream stream = new FileStream(filePath, FileMode.Open);
            HttpResponseMessage response = new HttpResponseMessage(HttpStatusCode.OK);
            response.Content = new StreamContent(stream);
            response.Content.Headers.ContentType = new MediaTypeHeaderValue("application/octet-stream");
            response.Content.Headers.ContentDisposition = new ContentDispositionHeaderValue("attachment")
            
                    FileName = HttpUtility.UrlEncode(fileName)
            ;
            response.Headers.Add("Access-Control-Expose-Headers", "FileName");
            response.Headers.Add("FileName", HttpUtility.UrlEncode(fileName));
            return response;
    

IHttpActionResult


????IHttpActionResult Web API 2 中引入了接口。 从根本上来说,用于将其他类型的值转换为HttpResponseMessage类型值的工厂。果控制器操作返回IHttpActionResult,Web API 调用ExecuteAsync方法创建HttpResponseMessage。 然后它会将转换HttpResponseMessage到 HTTP 响应消息。我个人比较用的多。使用IHttpActionResult:

  • 测试时更加简单方便。
  • 在单独的类创建 HTTP 响应的常见逻辑,响应的内容为HttpResponseMessage。
  • 通过隐藏构造响应的低级细节,使控制器操作的意图更加清晰。

下面是一个和返回值为void一样功能的VoiResult,该类实现了IHttpActionResult仅返回状态代码 204 (无内容) 的空 HTTP 响应。

    /// <summary>
    /// 一个无响应内容的响应信息
    /// </summary>
    public class VoidResult : IHttpActionResult
    

            HttpRequestMessage request;

            public VoidResult(HttpRequestMessage httpRequest)
            
                     this.request = httpRequest;
            
            public VoidResult(ApiController controller)
            
                    this.request = controller.Request;
            

            public Task<HttpResponseMessage> ExecuteAsync(CancellationToken cancellationToken)
            
                     return Task.FromResult<HttpResponseMessage>(new HttpResponseMessage(HttpStatusCode.NoContent)  RequestMessage = request );
            
    

????调用代码:

    public IHttpActionResult Get()
    
        return new VoidResult(Request);            
    

????HTTP 响应:

    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-SourceFiles: =?UTF-8?B?RTpcZ2l0SHViXFdlYkFQSVN0dWR5QXBwbGljYXRpb25cV2ViQVBJU3R1ZHlBcHBsaWNhdGlvblxhcGlcUmV0dXJuVmFsdWU=?=
    X-Powered-By: ASP.NET

????该示例说明了通过IHttpActionResult来构造响应的具体细节,使控制器操作的意图更加清晰和复用。
????IHttpActionResult包含一个方法ExecuteAsync,以便以异步方式创建HttpResponseMessage实例。

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

????如果控制器操作返回IHttpActionResult,Web API 调用ExecuteAsync方法创建HttpResponseMessage。 然后它会将转换HttpResponseMessage到 HTTP 响应消息。一般情况下我们只需要使用ApiController类内置的方法即可,方法内生成的instance定义在System.Web.Http.Results下。

方法 实例的类名 响应信息 响应内容
OK() OKResult 200 (正常)
Ok(T content) OkNegotiatedContentResult 200 (正常 序列化的结果
Json(T content) JsonResult 200 Json序列化的结果
Json(T content, JsonSerializerSettings serializerSettings) JsonResult 200 Json序列化的结果
NotFound() NotFoundResult 404
Redirect(..) RedirectResult 跳转
RedirectToRoute(...) RedirectToRouteResult 跳转
ResponseMessage(HttpResponseMessage response) ResponseMessageResult [别用浪费资源]
StatusCode(HttpStatusCode status) StatusCodeResult 输入的状态码
Unauthorized(params AuthenticationHeaderValue[] challenges) UnauthorizedResult 401 未授权的信息明细

void


????如果Web API Action返回类型为void,Web API 仅返回状态代码 204 (无内容) 的空 HTTP 响应。

    [HttpGet]
    public void Test()
    
        //连接测试
           

????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?RTpcLk5FVCBNVkMgIEFDRSBhZG1pblxXZWJcYXBpXEF1dGhvcml6YXRpb24=?=
    X-Powered-By: ASP.NET

某些其他类型


????对于所有其他返回类型,Web API 使用媒体格式化程序要序列化的返回值。 Web API 将序列化的值写入到响应正文。 响应状态代码为 200 (正常)。似乎所有类型都可以作为返回值,其实不然。再说这一问题前线看看什么样的实例能作为返回值。

  • 值类型但是其值为null,可空的值不在其范围内例如(int不可以返回nullNullable 也就是int?是可以返回为null的)
  • 类型不是泛型并且也不是Nullable<>类型的null实例不能做为返回值。
  • 不能被赋值给新实例的实例不能作为返回值

????某些其他类型返回值的控制器最终回传的是什么格式的数据:回执的数据格式决定在于请求的Accept参数的第一个格式(不包括txt,如果是/则返回Json)或者是在Global.asax里的设置或被调用的设置。

    Produce[] produces = new Produce[] 
        new Produceid=1,Name="自动化测试3",Price=11.2,
        new Produceid=2,Name="自动化测试2",Price=12.2 ,
        new Produceid=3,Name="自动化测试2",Price=13.2 
    ;
    [HttpGet]
    public Produce[] Test()
    
        return produces;
    

????HTTP 响应:

    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-SourceFiles: =?UTF-8?B?RTpcLk5FVCBNVkMgIEFDRSBhZG1pblxXZWJcYXBpXEF1dGhvcml6YXRpb24=?=
    X-Powered-By: ASP.NET

????数据内容为:

    ["id":1,"Name":"自动化测试3","Price":11.2,"id":2,"Name":"自动化测试2","Price":12.2,"id":3,"Name":"自动化测试2","Price":13.2]

????既然那么多的数据类型都可以作为返回值,那么执行Web Api是怎么处理返回值的呢?我们通过查看源码可以直到,最终是由ApiControllerActionInvoker.InvokeActionAsyncCore 来执行Action的。在InvokeActionAsyncCore可中将返回值作为以下几类处理

  • IHttpActionResult:该类型直接调用ExecuteAsync方法来获取一个HttpResponseMessage实例,将该实例返回;
  • HttpResponseMessage:将实例设置RequestMessage后直接返回
  • void: 返回一个新的HttpResponseMessage实例,设置其HttpStatusCode为NoContent
  • 不在上述类型中的类型:返回一个新的HttpResponseMessage实例,设置其HttpStatusCode为NoContent,Content为ObjectContent<T >。

总结归纳


  1. WEB API2 的最终返回值的类型为HttpResponseMessage,其他的返回值类型会经过一系列的处理形成一个HttpResponseMessage实例。
  2. 除了返回JsonResult实例返回的数据格式是Json外,其他的返回格式按请求或者设置而定。

以上是关于ASP.NET Web API 2 的返回结果的主要内容,如果未能解决你的问题,请参考以下文章

从 ASP.NET Web API ASP.NET Core 2 返回 HTML 并获取 http 状态 406

Asp.net MVC 与 Asp.net Web API 区别

是否有推荐的方法来使用 ASP.NET Web API 返回图像

ASP.NET Web API 2 Bearer Token 重定向到登录页面而不是返回 401

如何测试返回 Ok(object) 的 ASP.NET Core 2.2 Web API GET IActionResult?

ASP.NEt MVC 使用 Web API 返回 Razor 视图