当前位置 > 首页 > Asp.net

Asp.net web Api源码分析-HttpControllerDispatcher (Controller的创建)

2012-12-4 16:32:00来源:Asp.net

紧接着上文Asp.net web Api源码分析-HttpServer的创建最后我们提到了一个HttpRoutingDispatcher,一看这个类的名字我想我们也就能猜到它是干什么的吧。查找路由信息,那么找到路由后干什么了,是不是就该调用handler了?

首先还是让我们来看看HttpRoutingDispatcher的SendAsync方法


  protected override Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
        {
            // Lookup route data, or if not found as a request property then we look it up in the route table
            IHttpRouteData routeData;
            if (!request.Properties.TryGetValue(HttpPropertyKeys.HttpRouteDataKey, out routeData))
            {
                routeData = _configuration.Routes.GetRouteData(request);
                if (routeData != null)
                {
                    request.Properties.Add(HttpPropertyKeys.HttpRouteDataKey, routeData);
                }
                else
                {
                    return TaskHelpers.FromResult(request.CreateErrorResponse(
                        HttpStatusCode.NotFound,
                        Error.Format(SRResources.ResourceNotFound, request.RequestUri),
                        SRResources.NoRouteData));
                }
            }

            RemoveOptionalRoutingParameters(routeData.Values);

            var invoker = routeData.Route.Handler == null ? _defaultInvoker : new HttpMessageInvoker(routeData.Route.Handler, disposeHandler: false);
            return invoker.SendAsync(request, cancellationToken);

        }

首先这里先从HttpRequestMessage中获取路由信息,如果不能获取则调用_configuration.Routes.GetRouteData来获取路由信息,默认情况下这里是可以获取到路由信息(因为在HttpControllerHandler的BeginProcessRequest方法中有这么一句 request.Properties[HttpPropertyKeys.HttpRouteDataKey] = _routeData;)然后调用RemoveOptionalRoutingParameters方法来移除路由中的可选参数。

这里的routeData我们知道它是在HttpControllerHandler的构造函数中创建的一个HostedHttpRouteData实例,其Route属性是一个HostedHttpRoute实例,routeData.Route.Handler就是我们路由中注册的handler,默认情况下我们没有注册自己的handler,所以这里的invoker=_defaultInvoker,这里的_defaultInvoker=      new HttpMessageInvoker(new HttpControllerDispatcher(configuration)),所以调用invoker的SendAsync方法,其实就是调用HttpControllerDispatcher的SendAsync方法

HttpControllerDispatcher这个名称我们就可以猜测到它是把当前http请求交给特定的Controller来处理。HttpControllerDispatcher的SendAsync方法差不多就是一个内联函数,直接调用内部的SendAsyncInternal方法:

private Task<HttpResponseMessage> SendAsyncInternal(HttpRequestMessage request, CancellationToken cancellationToken)
{
if (request == null)
{
throw Error.ArgumentNull("request");
}

IHttpRouteData routeData = request.GetRouteData();
Contract.Assert(routeData != null);
HttpControllerDescriptor httpControllerDescriptor = ControllerSelector.SelectController(request);
if (httpControllerDescriptor == null)
{
return TaskHelpers.FromResult(request.CreateErrorResponse(
HttpStatusCode.NotFound,
Error.Format(SRResources.ResourceNotFound, request.RequestUri),
SRResources.NoControllerSelected));
}

IHttpController httpController = httpControllerDescriptor.CreateController(request);
if (httpController == null)
{
return TaskHelpers.FromResult(request.CreateErrorResponse(
HttpStatusCode.NotFound,
Error.Format(SRResources.ResourceNotFound, request.RequestUri),
SRResources.NoControllerCreated));
}

// Set the controller configuration on the request properties
HttpConfiguration requestConfig = request.GetConfiguration();
if (requestConfig == null)
{
request.Properties.Add(HttpPropertyKeys.HttpConfigurationKey, httpControllerDescriptor.Configuration);
}
else
{
if (requestConfig != httpControllerDescriptor.Configuration)
{
request.Properties[HttpPropertyKeys.HttpConfigurationKey] = httpControllerDescriptor.Configuration;
}
}

// Create context
HttpControllerContext controllerContext = new HttpControllerContext(httpControllerDescriptor.Configuration, routeData, request);
controllerContext.Controller = httpController;
controllerContext.ControllerDescriptor = httpControllerDescriptor;

return httpController.Execu

  • ASP.NET读取Excel文件的三大方法浅析

    2011-9-6 9:43:00

    ASP.NET读取Excel文件的三大方法浅析 http://developer.51cto.com 2009-07-28 10:36 佚名 百度空间 我要评论( 0 )

  • 我的模板分析引擎类PHP的.net开发方法--功能实现篇

    2007-8-24 22:19:00

    摘要: 昨天发了一篇关于模板的功能介绍的文章,今天我想说说我为什么想设计一个自己的模板分析程序而不愿意使用微软老大给我们做好的近似完美的一切.   做网站的本质无非是一些html加一点点css,再放

  • 用C#实现对Oracle 存储过程/函数/包的调试(附源代码)

    2007-5-9 22:59:00

    摘要: C# 调用Oracle程序包SYS.DBMS_DEBUG实现对存储过程/函数/包的调试 阅读全文 Shark Xu 2007-05-08 18:38 发表评论

  • 有关.NET Framework4中安全模型的改变及有关问题

    2010-9-26 12:06:00

    您好 我们知道.NET Framework 4中对安全模型做了很大改进,基本上抛弃了原先的CAS,而引入了所谓的透明安全Level 2. 我有几个问题是 1.如果一个程序集,被标记为:S

  • Asp.net web Api源码分析-Filter

    2012-12-5 11:51:00

    紧接着上文 Asp.net web Api源码分析-HttpActionDescriptor的创建 HttpActionDescriptor现在已经创建好了,在这里个人再次提醒一下, 建议大家在路

  • OnePiece 之 Asp.Net 菜鸟也来做开发(二)

    2009-8-22 9:57:00

    摘要: 我是一只小小小菜鸟,但是我也怀揣着做开发的梦想;我是一只小小小小菜鸟,但是我也想长成大鸟飞向天空。某牛说过“只要努力,早晚会有属于你的天地!”于是我相信,菜鸟也能做开发,菜鸟也会在不久的将来

  • 基于WS-AtomicTransaction标准的WCF远程分布式事务(补充)

    2007-5-27 0:10:00

    在测试WCF 的WS-AT协议的时候发现,虽然wsHttpBinding只支持WS-AtomicTransaction,但是当我没有配置MSDTC支持WS-AT协议,或者没有启用WS-AT协议,事务

  • Fun with IronPython & GLEE

    2007-4-3 7:06:00

    I started this exercise thinking about visualizing the methods tree in a diagram. There are severa

  • DevExpress CodeRush Xpress for C# & VB.NET

    2009-7-1 12:20:00

    Mark Miller from DevExpress just posted an incredible article on CodeRush Xpress. Here is a

  • 使用FxCop做代码检查和优化

    2007-3-14 13:56:00

    摘要: FxCop的使用可以自动进行一些代码方面的测试,同时有帮助提高代码执行效率和学习编码规范,从而提供代码的整体质量 阅读全文 jchdong 2007-03-14 13:46 发