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. saiku源代码安装

    以前的文章介绍了如何直接安装saiku,http://www.cnblogs.com/liqiu/p/5183894.html .这里面偷懒没有源代码编译,不过这几天也就这么用了. 最近随着使用的深入 ...

  2. SQL语句转摘

    http://www.cnblogs.com/Olive116/p/3271706.html 收藏没有用,来收到留链接

  3. python 安装加环境变量

    pip install sth --global-option="build_ext" --global-option="-I/usr/local/include&quo ...

  4. Offer_answer_with_SDP_rfc3264

    Network Working Group J. RosenbergRequest for Comments: 3264 dynamicsoftObsoletes: 2543 H. Schulzrin ...

  5. 让我们一起Go(十二)

    前言: 上篇中,我们讲到了在Go语言中如何定义方法,今天,我们将进一步深入Go语言的面向对象编程. 一.Go语言中的接口 首先来看一个最基本的接口: 和定义一个结构体类似,只不过将struct换成了i ...

  6. Qt5 从头学(1)-- 环境

    对我来说MFC太过麻烦了,同样是桌面开发工具,Qt就完全不一样了.Qt使用C++语言可以轻松实现"一次编写,到处编译"的跨平台性能,并且可以做出很多炫酷的界面效果.目前支持几乎所有 ...

  7. maven中文乱码问题——打包错误

    工程采用GBK编码, web应用中的配置文件打包后,war包里的配置文件里的中文成乱码.   用notepad++打开后,可以看到是用utf-8格式的(可以通过菜单中的[格式]查看),也就是说,在经过 ...

  8. ODB学习笔记之基础环境搭建

      一,简介 ODB是应用于C++的一个开源.跨平台.跨数据库的对象关系映射(ORM)系统. 它可以让你持久化C++对象到关系数据库,而不必处理表.列或者SQL,无需手动编写任何映射代码. ODB支持 ...

  9. HDU4550+贪心

    /* 贪心 先挑出最小的Mm,然后在Mm左侧的按情况考虑,右侧的按顺序排列. */ #include<stdio.h> #include<string.h> #include& ...

  10. 【分享】Matlab R2015a 发布啦!

    本博客所有文章分类的总目录:http://www.cnblogs.com/asxinyu/p/4288836.html Matlab和C#混合编程文章目录:http://www.cnblogs.com ...