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)
ASP.NET WebAPI 12 Action的执行的更多相关文章
- ASP.NET WebAPI 10 Action的选择(二)
在本系列的第二篇简要的讲述了Action的选择条件本篇深入讲述一下Action选择的过程在上一篇中我们已经讲到了Controller的激活过程中已经说到了设置Controller的Controller ...
- 白话学习MVC(八)Action的执行二
一.概述 上篇博文<白话学习MVC(七)Action的执行一>介绍了ASP.NET MVC中Action的执行的简要流程,并且对TempData的运行机制进行了详细的分析,本篇来分析上一篇 ...
- Asp.Net WebApi Action命名中已‘Get’开头问题
ApiController 中的Action 命名已‘Get’开头,Post方法提交失败 场景: 1.action命名使用Get开头 /// <summary> /// 获取用户的未读消息 ...
- Asp.net mvc 中Action 方法的执行(三)
[toc] 前面介绍了 Action 方法执行过程中的一些主要的组件以及方法执行过程中需要的参数的源数据的提供以及参数的绑定,那些都可以看作是 Action 方法执行前的一些必要的准备工作,接下来便将 ...
- Asp.net mvc 中Action 方法的执行(一)
[toc] 在 Aps.net mvc 应用中对请求的处理最终都是转换为对某个 Controller 中的某个 Action 方法的调用,因此,要对一个请求进行处理,第一步,需要根据请求解析出对应的 ...
- ASP.NET Core 2.2 : 十七.Action的执行(Endpoint.RequestDelegate后面的故事)
上一章介绍了经过路由的处理,一个请求找到了具体处理这个请求的EndPoint,并最终执行它的RequestDelegate方法来处理这个Httpcontext.本章继续这个处理进程,按照惯例,依然通过 ...
- ASP.NET WebApi 文档Swagger深度优化
本文版权归博客园和作者吴双本人共同所有,转载和爬虫请注明博客园蜗牛原文地址,cnblogs.com/tdws 写在前面 请原谅我这个标题党,写到了第100篇随笔,说是深度优化,其实也并没有什么深度 ...
- ASP.NET WebApi 文档Swagger中度优化
本文版权归博客园和作者吴双本人共同所有,转载和爬虫请注明原文地址:www.cnblogs.com/tdws 写在前面 在后台接口开发中,接口文档是必不可少的.在复杂的业务当中和多人对接的情况下,简 ...
- ASP.NET WEBAPI 的身份验证和授权
定义 身份验证(Authentication):确定用户是谁. 授权(Authorization):确定用户能做什么,不能做什么. 身份验证 WebApi 假定身份验证发生在宿主程序称中.对于 web ...
随机推荐
- C# 调用百度地图Web服务API
最近公司项目中需要根据两个地点的交通路径和距离做一些数据推荐,为了程序的稳定和用户体验所以想从百度地图 API 采集数据保存到数据库中,经过一翻研究之后选定了百度地图 Web 服务 API 中的 Di ...
- 程序员之路:以Android证道
大道三千,何以证道? 最近有私信.邮件给我咨询一些职业生涯规划的同学,我在这里以过来人的身份给大家一些建议. 任何行业,任何职位,无论高低,无论大小,都可以分为广博.精深两个方向. 精深自然指的是在某 ...
- linq join多字段
from VS in m2db.Inf_VehicleSale join RS1 in m2db.His_RecSale on new { VS.vehicleCode, auctionCode=VS ...
- [转]使用ant让Android自动打包的build.xml,自动生成签名的apk文件(支持android4.0以上的版本)
在android4.0以后的sdk里那个脚本就失效了,主要是因为 apkbuilder这个程序不见了: 人家sdk升级,我们的脚本也要跟上趟,修改一下喽. 上网一查,大家的文章还停留在我去年的脚本程度 ...
- 安卓开发笔记——深入Activity
在上一篇文章<安卓开发笔记——重识Activity >中,我们了解了Activity生命周期的执行顺序和一些基本的数据保存操作,但如果只知道这些是对于我们的开发需求来说是远远不够的,今天我 ...
- 【转】Linux下svn常用指令
转自: http://blog.csdn.net/myarrow/article/details/8110858 1.将文件checkout到本地目录svn checkout path(path是服务 ...
- 用C#实现修改网页数据
背景 由于某宝最近升级,导致朋友买的刷单软件不能用了:在又付过钱之后,那个刷单软件供应商竟然捐款跑路了...于是,朋友委托我做一个功能一样的软件.功能 他给我描述的软件功能,是这个样子的: ...
- Java--解决java compiler level does not match the version of the installed java project facet错误
从网上下载了个项目,导入eclipse时发现如下错误: 检查后发现原来是JDK版本不一致的问题,项目的默认JDK配置是1.5,而自己电脑上是1.7. 需要修改两个地方的配置,如下图所示: 修改一: 修 ...
- Go Go
Go Go *:first-child { margin-top: 0 !important; } body>*:last-child { margin-bottom: 0 !important ...
- SQL Server中的事务日志管理(1/9):事务日志概况
当一切正常时,没有必要特别留意什么是事务日志,它是如何工作的.你只要确保每个数据库都有正确的备份.当出现问题时,事务日志的理解对于采取修正操作是重要的,尤其在需要紧急恢复数据库到指定点时.这系列文章会 ...