zoukankan      html  css  js  c++  java
  • ASP.NET WebAPI 12 Action的执行

    Action的激活大概可以分为如下两个步骤:Action对应方法的调用,执行结果的协商。在WebAPI中由HttpActionInvoker(System.Web.Http.Controllers)进行Action的执行。

     

    public interface IHttpActionInvoker
    
     { 
    
    Task<HttpResponseMessage> InvokeActionAsync(HttpActionContext actionContext, CancellationToken cancellationToken); 
    
     }
    

      

    HttpActionInvoker也是"标准化组件",,WebAPI的默认实现为:ApiControllerActionInvoker (System.Web.Http.Controllers,ApiControllerActionInvoker的实现中Action方法的调用实际上交由HttpActionDescriptor的ExecuteAsync的方法去执行,内容协商交由ContentNegotiator处理。

    Action的执行

    ActionExecutor

    ReflectedHttpActionDescriptor在ExecuteAsync方法实现中把Action的执行又交给了它的内部类ActionExecutor

     

    public class ReflectedHttpActionDescriptor : HttpActionDescriptor
    
     {
    
    public abstract Task<object> ExecuteAsync(HttpControllerContext controllerContext, IDictionary<string, object> arguments, CancellationToken cancellationToken); 
    
     }
    

      

    ReflectedHttpActionDescriptor其实又将Action的执行交由其内部类ActionExecutor执行。

     

    public override Task<object> ExecuteAsync(HttpControllerContext controllerContext, IDictionary<string, object> arguments, CancellationToken cancellationToken) 
    
     { 
    
    if (controllerContext == null) 
    
     { 
    
    throw Error.ArgumentNull("controllerContext"); 
    
     } 
    
     
    
    if (arguments == null) 
    
     { 
    
    throw Error.ArgumentNull("arguments"); 
    
     } 
    
     
    
    if (cancellationToken.IsCancellationRequested) 
    
     { 
    
    return TaskHelpers.Canceled<object>(); 
    
     } 
    
     
    
    try
    
     { 
    
    object[] argumentValues = PrepareParameters(arguments, controllerContext); 
    
    return _actionExecutor.Value.Execute(controllerContext.Controller, argumentValues); 
    
     } 
    
    catch (Exception e) 
    
     { 
    
    return TaskHelpers.FromError<object>(e); 
    
     } 
    
     }
    

      

    ActionExecutor对于Action的执行采用的是表达示树的方式,这个后续我会写一个Action执行的demo。

    内容协商(结果序列化)

    在之前的参数绑定一文中讲到参数的反序列化是根据请求头信息中的Content-Type获取不同的序列化对象,在对结果进行序列化的过程中也是如此,不过获取的头信息是Accept。

    对于Action的返回结果大概有如下几种情况:void,,object,ActionResult,HttpResponseMessage。对于HttpResponseMessage因为整个HttpMessageHandler的返回值就是HttpResponseMessage,所以可以直接返回.对于IActionResult,它本身有ExecuteAsync方法(返回结果)可以返回HttpResponseMessage。不同的ActionResult会用不用的序列化策略.JsonResult<T>是直接将结果序列化Json形式。对于 OkNegotiatedContentResult类型,因为它不像JsonResult<T>一样有明确的序列化方式,所以这个时候就要根据客户端请求进行获取序列化。这种方式同样适用于object与void类型的返回值,但这个具体的实现由HttpResponseMessage的扩展方法CreateResponse完成。

    ContentNegotiator

    IContentNegotiator(System.Net.Http.Formatting)在WebAPI中也是"标准化组件",它的默认实现为DefaultContentNegotiator(System.Net.Http.Formatting)

     

    public interface IContentNegotiator
    
     { 
    
    ContentNegotiationResult Negotiate(Type type, HttpRequestMessage request, IEnumerable<MediaTypeFormatter> formatters); 
    
     }
    

      

    IContentNegotiator只有一个Negotiator方法,该方法的返回值ContentNegotiationResult 包含了MedioType信息与获取到的序列化对象。

     

    public class ContentNegotiationResult
    
     { 
    
    public MediaTypeFormatter Formatter { get; set; } 
    
    public MediaTypeHeaderValue MediaType { get; set; } 
    
     }
    

      

    在demo中我自定义了一个MyContentNegotiationResult<T>用来展示内容协商的具体处理逻辑。

    源码

    Github: https://github.com/BarlowDu/WebAPI (API_12)

  • 相关阅读:
    如何用互联网的思维开一家有逼格的客栈?
    create和grant配合使用,对Mysql进行创建用户和对用户授权
    Nginx 403 forbidden原因及故障模拟重现(转载)
    企业级缓存系统varnish应用
    实现基于Haproxy+Keepalived负载均衡高可用架构
    企业级监控zabbix基础
    实现基于Keepalived主从高可用集群网站架构
    实现基于LVS负载均衡集群的电商网站架构
    实现基于lnmp的电子商务网站
    CentOS6编译LAMP基于FPM模式的应用wordpress
  • 原文地址:https://www.cnblogs.com/gangtianci/p/4993080.html
Copyright © 2011-2022 走看看