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)

ASP.NET WebAPI 12 Action的执行的更多相关文章

  1. ASP.NET WebAPI 10 Action的选择(二)

    在本系列的第二篇简要的讲述了Action的选择条件本篇深入讲述一下Action选择的过程在上一篇中我们已经讲到了Controller的激活过程中已经说到了设置Controller的Controller ...

  2. 白话学习MVC(八)Action的执行二

    一.概述 上篇博文<白话学习MVC(七)Action的执行一>介绍了ASP.NET MVC中Action的执行的简要流程,并且对TempData的运行机制进行了详细的分析,本篇来分析上一篇 ...

  3. Asp.Net WebApi Action命名中已‘Get’开头问题

    ApiController 中的Action 命名已‘Get’开头,Post方法提交失败 场景: 1.action命名使用Get开头 /// <summary> /// 获取用户的未读消息 ...

  4. Asp.net mvc 中Action 方法的执行(三)

    [toc] 前面介绍了 Action 方法执行过程中的一些主要的组件以及方法执行过程中需要的参数的源数据的提供以及参数的绑定,那些都可以看作是 Action 方法执行前的一些必要的准备工作,接下来便将 ...

  5. Asp.net mvc 中Action 方法的执行(一)

    [toc] 在 Aps.net mvc 应用中对请求的处理最终都是转换为对某个 Controller 中的某个 Action 方法的调用,因此,要对一个请求进行处理,第一步,需要根据请求解析出对应的 ...

  6. ASP.NET Core 2.2 : 十七.Action的执行(Endpoint.RequestDelegate后面的故事)

    上一章介绍了经过路由的处理,一个请求找到了具体处理这个请求的EndPoint,并最终执行它的RequestDelegate方法来处理这个Httpcontext.本章继续这个处理进程,按照惯例,依然通过 ...

  7. ASP.NET WebApi 文档Swagger深度优化

    本文版权归博客园和作者吴双本人共同所有,转载和爬虫请注明博客园蜗牛原文地址,cnblogs.com/tdws   写在前面 请原谅我这个标题党,写到了第100篇随笔,说是深度优化,其实也并没有什么深度 ...

  8. ASP.NET WebApi 文档Swagger中度优化

    本文版权归博客园和作者吴双本人共同所有,转载和爬虫请注明原文地址:www.cnblogs.com/tdws   写在前面 在后台接口开发中,接口文档是必不可少的.在复杂的业务当中和多人对接的情况下,简 ...

  9. ASP.NET WEBAPI 的身份验证和授权

    定义 身份验证(Authentication):确定用户是谁. 授权(Authorization):确定用户能做什么,不能做什么. 身份验证 WebApi 假定身份验证发生在宿主程序称中.对于 web ...

随机推荐

  1. 在CodedUI中使用JQuery选择器

    在CodedUI中使用JQuery选择器http://automationqa.com/forum.php?mod=viewthread&tid=3574&fromuid=29

  2. mysql int(1) 与 tinyint(1) 有什么区别?

    From: http://www.cnblogs.com/xiaochaohuashengmi/archive/2011/08/25/2153016.html mysql int(1) tinyint ...

  3. 为什么这样写js:(function ($) { })(jQuery);

    很多时候,会这样写js,比如公司的项目里面的js页面都这样,所以我就想搞清楚意思: <script language="javascript" type="text ...

  4. 页面头部title、description、keywords标签的优化

    页面头部优化<Head></Head>中间的区域中间的区域,我们称为网页的头部.在网页的头部中,通常存放一些介绍页面内容的信息,例如页面标题.描述及关键字等等.在头部优化中,除 ...

  5. 【NS2仿真】UDP协议

    # # cbr # \ # udp sink # \ / # n0--------5M 2ms---------n1 # # set ns [new Simulator] set f [open ou ...

  6. 【解决方案】VS2013外部工具中添加ildasm.exe

    VS2013安装在Win8.1的操作系统中,开始屏幕中找不到ildasm.exe没有显示,于是下面提供了一种方法将ildasm.exe工具添加到VS2013外部工具中,并将反编译的代码输出到VS201 ...

  7. codeforces C. Bits(数学题+或运算)

    题意:给定一个区间,求区间中的一个数,这个数表示成二进制的时候,数字1的个数最多! 如果有多个这样的数字,输出最小的那个! 思路:对左区间的这个数lx的二进制 从右往左将0变成1,直到lx的值大于右区 ...

  8. 2014 网选 5014 Number Sequence(异或)

    /* 题意:a, b两个序列,规定由[0, n]区间的数! 求 a[i] ^ b[i] 的和最大! 思路:如果数字 n的二进制有x位, 那么一定存在一个数字m,使得n^m的所有二进制位 都是1,也就是 ...

  9. DDD:关于模型的合法性,Entity.IsValid()合理吗?

    背景 见过很多框架(包括我自己的)都会在实体的定义中包含一个IsValid()方法,用来判断实体的合法性,是否应该这样设计呢?本文就这个问题介绍一点想法,希望大家多批评. 实体能否处于“非法”状态? ...

  10. NopCommerce之任务执行

    NOP任务提供两种:手动执行(立即)和定时执行两种. 首先来说下手动任务执行过程,下图是NOP定时任务管理界面: 从上面可以看出,我们可以选择具体的任务来手动执行任务(立即执行),当点击[立即执行]按 ...