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. 关于IT概念的一些思考

    同事提及“软件工程.软件生命周期.项目管理.CMMI.IPD.RUP.UML及UML建模.面向对象分析与设计.需求分析.系统分析与设计……等等,它们到底是什么?它们之间有什么关系?”   下面是个人见 ...

  2. Auto CAD 2013的故障解决方法

    一.问题的提出 Auto CAD 2013在使用过程中出现了错误:“安全系统(软件锁许可管理器) 不起作用或未正确安装.” 二.问题的分析 网络上很多地方转载了这么一个方法: 1) 启动Windows ...

  3. Base64 算法原理,以及编码、解码【加密、解密】 介绍

    Base64编码,是我们程序开发中经常使用到的编码方法.它是一种基于用64个可打印字符来表示二进制数据的表示方法.它通常用作存储.传输一些二进制数据编码方法!也是MIME(多用途互联网邮件扩展,主要用 ...

  4. 文件比对工具(Beyond Compare)

    文件比对工具: 工具名称:Beyond Compare 版本号:v3.3.13 下载地址:http://i.cnblogs.com/Files.aspx 官网最新版本下载地址:http://www.s ...

  5. 在redhat上搭建redmine

    搞个项目管理的东西 找了下还是redmine比较合适,行动action: 1.ruby 额 是的你没有看错 需要先安装一个ruby的环境.话说这个安装起来很是纠结,本来想用yum 结果咩有成功,于是乎 ...

  6. NGUI 界面自适应

    关于 NGUI 的界面自动适应不同的手机分辨率,网上已经够多的了.如果你点进了这个网页,推荐一下这一篇吧: http://www.xuanyusong.com/archives/2536 下面是我自己 ...

  7. 调用Ajax返回500错误的解决方法

    看代码: public ActionResult UserLogin(LogOnModel model) { #region 验证码验证 #endregion OperationResult resu ...

  8. bootstrap插件学习-bootstrap.popover.js

    先看bootstrap.popover.js的结构 var Popover = function ( element, options ){} //构造器 Popover.prototype = {} ...

  9. Gulp:新一代前端构建利器

    1.什么是Gulp gulp.js 是一种基于流的,代码优于配置的新一代构建工具. Gulp 和 Grunt 类似.但相比于 Grunt 的频繁的 IO 操作,Gulp 的流操作,能更快地完成构建. ...

  10. android小技巧和注意事项

    在listView 或者 gridView 的使用中,通常不仅仅为了展现数据,更多的是操作数据.于是当控件重合在一起时,我们需要添加事件.就会出现一个问题,当点击一个控件和长按这个控件时,常常出现长按 ...