当前位置 > 首页 > Asp.net

Asp.net web Api源码分析-HttpActionDescriptor的创建

2012-12-4 21:46:00来源:Asp.net

紧接着上文Asp.net web Api源码分析-HttpControllerDispatcher (Controller的创建)这里已经创建好了IHttpController,现在让我们来看看它的ExecuteAsync方法,这个方法很是复杂啊。

public virtual Task<HttpResponseMessage> ExecuteAsync(HttpControllerContext controllerContext, CancellationToken cancellationToken)
{
if (_request != null)
{
// if user has registered a controller factory which produces the same controller instance, we should throw here
throw Error.InvalidOperation(SRResources.CannotSupportSingletonInstance, typeof(ApiController).Name, typeof(IHttpControllerActivator).Name);
}

Initialize(controllerContext);

// We can't be reused, and we know we're disposable, so make sure we go away when
// the request has been completed.
if (_request != null)
{
_request.RegisterForDispose(this);
}

HttpControllerDescriptor controllerDescriptor = controllerContext.ControllerDescriptor;
ServicesContainer controllerServices = controllerDescriptor.Configuration.Services;
HttpActionDescriptor actionDescriptor = controllerServices.GetActionSelector().SelectAction(controllerContext);
HttpActionContext actionContext = new HttpActionContext(controllerContext, actionDescriptor);

IEnumerable<FilterInfo> filters = actionDescriptor.GetFilterPipeline();

FilterGrouping filterGrouping = new FilterGrouping(filters);

IEnumerable<IActionFilter> actionFilters = filterGrouping.ActionFilters;
IEnumerable<IAuthorizationFilter> authorizationFilters = filterGrouping.AuthorizationFilters;
IEnumerable<IExceptionFilter> exceptionFilters = filterGrouping.ExceptionFilters;

// Func<Task<HttpResponseMessage>>
Task<HttpResponseMessage> result = InvokeActionWithAuthorizationFilters(actionContext, cancellationToken, authorizationFilters, () =>
{
HttpActionBinding actionBinding = actionDescriptor.ActionBinding;
Task bindTask = actionBinding.ExecuteBindingAsync(actionContext, cancellationToken);
return bindTask.Then<HttpResponseMessage>(() =>
{
_modelState = actionContext.ModelState;
Func<Task<HttpResponseMessage>> invokeFunc = InvokeActionWithActionFilters(actionContext, cancellationToken, actionFilters, () =>
{
return controllerServices.GetActionInvoker().InvokeActionAsync(actionContext, cancellationToken);
});
return invokeFunc();
});
})();

result = InvokeActionWithExceptionFilters(result, actionContext, cancellationToken, exceptionFilters);

return result;
}

 

首先调用Initialize方法初始化ControllerContext、_request、_configuration,紧接着就创建一个HttpActionDescriptor

 HttpActionDescriptor actionDescriptor = controllerServices.GetActionSelector().SelectAction(controllerContext);

   在DefaultServices中有这么一句SetSingle<IHttpActionSelector>(new ApiControllerActionSelector());, 所以我们就知道controllerServices.GetActionSelector()返回的是一个 ApiControllerActionSelector实例。其中ApiControllerActionSelector的SelectAction 实现也比较简单:

    public virtual HttpActionDescriptor SelectAction(HttpControllerContext controllerContext)
        {
            ActionSelectorCacheItem internalSelector = GetInternalSelector(controllerContext.ControllerDescriptor);
            return internalSelector.SelectAction(controllerContext);

        }

我们首先来看看GetInternalSelector方法实现:、

   private ActionSelectorCacheItem GetInternalSelector(HttpControllerDescriptor controllerDescriptor)
        {
            // First check in the local fast cache and if not a match then look in the broader
            // HttpControllerDescriptor.Properties cache
            if (_fastCache == null)
            {
                ActionSelectorCacheItem selector = new ActionSelectorCacheItem(controllerDescriptor);
                Interlocked.CompareExchange(ref _fastCache, selector, null);
                return selector;
            }
            else if (_fastCache.HttpControllerDescriptor == controllerDescriptor)
            {
                // If the key matches and we already have the delegate for creating an instance then just execute it
                return _fastCache;
            }
            else
            {
                // If the key doesn't match then lookup/create delegate in the HttpControllerDescriptor.Properties for
                // that HttpControllerDescriptor instance
                ActionSelectorCacheItem selector


  • Anyone still running this place? weblogs.asp.net

    2009-11-14 17:29:00

    I’m getting a horrible amount of comment spam here on weblogs.asp.net lately. Anyone still maintain

  • UI自动化开发的一些技巧 - .NET部分

    2012-10-27 7:31:00

    一般来说,UI自动化测试开发过程中,尝试不同的方法去找界面上的控件是一个比较费时的事情,这是因为有些界面需要前期操作很多步骤才能到达目的界面查看控件树结构,如果一不小心把控件树结构理解错了,导致控件

  • 浅谈.NET中可用的定时器和计时器【上篇】

    2012-8-5 10:44:00

    .net中的计时问题可能每个人都会遇到,但是很少有人系统的总结,Baidu了下,无果,故写作本文。 本文旨在总结.net中可用的各种计时方法,介绍的是DebugLZQ知道的几种.net中的定时、计

  • ASP.NET MVC分页、ASP.NET MVC Ajax分页组件1.0发布!

    2010-1-4 20:44:00

    阅读: 1156 评论: 13 作者: 戴超 发表于 2010-01-04 11:47 原文链接 新年到!先给博客园的朋友们拜个年!祝大家新年快乐! 在实际项目的开发过程中!发现

  • .NET Community Mexico City

    2011-4-25 12:33:00

    I will be participating as an invited speaker in “Comunidad.NET” in Mexico City next Tuesday (April

  • Utilizando o Reflection no C#

    2009-5-12 23:47:00

    De vez em quando surge a necessidade de utilizar recursos em nossos códigos que est?o fora do ambi

  • 在SQL Server2005/2008中对记录进行分组,并获得每组前N条记录

    2009-11-3 9:11:00

    阅读: 163 评论: 2 作者: 银河使者 发表于 2009-11-03 08:41 原文链接 本文为原创,如需转载,请注明作者和出处,谢谢! 假设有一个表,SQL语句

  • Game program for kids less than 2 years :)

    2009-8-18 18:59:00

    My daughter Mariam (=Mary) one year old always coming to my pc when I doing some work and climbing

  • Sharepoint 浅谈

    2010-7-12 16:54:00

    作者: 寂寞的DBOY 发表于 2010-07-12 16:26 原文链接 阅读: 62 评论: 0 做Sharepoint项目,要分几个步骤:首先部署服务器和开发环境,然后实施代码管理,

  • 【解惑】这么多技术我该怎么学

    2009-9-9 9:24:00

    摘要: 经常有同学问“这么多技术我该怎么学,某某和某某两个技术哪个更有前途”。因此我写了下面的小文章,也算是和如鹏网所有同学的一个交流常见总结吧。一、这多东西啥时候能学完?现