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

紧接着上文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(SRResou
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值