• 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)

  • 相关阅读:
    Android
    十大基础有用算法之迪杰斯特拉算法、最小生成树和搜索算法
    【随想】android是个什么东西,andorid机制随想
    【Unity3D】【NGUI】Atlas的动态创建
    Java集合01----ArrayList的遍历方式及应用
    JAVA线程
    VC++的project文件
    selector的button选中处理问题
    单元測试和白盒測试相关总结
    leetCode(40):Path Sum
  • 原文地址:https://www.cnblogs.com/gangtianci/p/4993080.html
Copyright © 2020-2023  润新知