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

紧接着前文Asp.net web Api源码分析-HttpRequestMessage的创建 HttpRequestMessage实例已经创建好了,现在我们来看看  

Task responseBodyTask = _server.Value.SendAsync(request, CancellationToken.None)

                .Then(response => ConvertResponse(httpContextBase, response, request));

这里的_server.Value.SendAsync是真正处理http请求的,ConvertResponse只是处理结果而已的。我这里还是按早代码的执行顺序依次说吧。首先我们来看看这里的_server是个什么东东:

private static readonly Lazy<HttpMessageInvoker> _server =
            new Lazy<HttpMessageInvoker>(
                () =>
                {
                    HttpServer server = new HttpServer(GlobalConfiguration.Configuration, GlobalConfiguration.DefaultHandler);
                    return new HttpMessageInvoker(server);
                });

这里的_server是一个HttpMessageInvoker的实例,这里还需要一个HttpServer的变量。其中GlobalConfiguration的DefaultHandler定义如下:

  private static Lazy<HttpMessageHandler> _defaultHandler = new Lazy<HttpMessageHandler>(
            () => new HttpRoutingDispatcher(_configuration.Value));
  public static HttpMessageHandler DefaultHandler
        {
            get { return _defaultHandler.Value; }
        }

DefaultHandler属性其实是一个HttpRoutingDispatcher实例。这里我们首先看看HttpRoutingDispatcher的构造函数:

public class HttpRoutingDispatcher : HttpMessageHandler
{
   private readonly HttpConfiguration _configuration;
   private readonly HttpMessageInvoker _defaultInvoker;
    public HttpRoutingDispatcher(HttpConfiguration configuration)
            : this(configuration, new HttpControllerDispatcher(configuration))
        {
        }
        public HttpRoutingDispatcher(HttpConfiguration configuration, HttpMessageHandler defaultHandler)
        {
            _configuration = configuration;
            _defaultInvoker = new HttpMessageInvoker(defaultHandler);
        }

}

在创建HttpRoutingDispatcher实例的时候这里需要创建一个HttpControllerDispatcher、 HttpMessageInvoker实例,而HttpControllerDispatcher、HttpMessageInvoker这里的构造都比 较简单美什么特别之处。

同样这里的HttpServer的创建也很简单

public abstract class DelegatingHandler : HttpMessageHandler

    public class HttpServer : DelegatingHandler
    {
      public HttpServer(HttpConfiguration configuration, HttpMessageHandler dispatcher)
        {
            _dispatcher = dispatcher;
            _configuration = configuration;
        }
    }

现在我们知道这里的_server的创建,那么它的SendAsync又是怎么执行的了。HttpMessageInvoker类中的SendAsync方法实现很简单主要就一句 Task<HttpResponseMessage> retObject = this.handler.SendAsync(request, cancellationToken);在这里实际就是调用HttpServer的SendAsync方法。而HttpServer的SendAsync实现方式如下:

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

            if (_disposed)
            {
                return TaskHelpers.FromResult(request.CreateErrorResponse(HttpStatusCode.ServiceUnavailable, SRResources.HttpServerDisposed));
            }

            // The first request initializes the server
            EnsureInitialized();

            // Capture current synchronization context and add it as a parameter to the request
            SynchronizationContext context = SynchronizationContext.Current;
            if (context != null)
            {
                request.Properties.Add(HttpPropertyKeys.SynchronizationContextKey, context);
            }

            // Add HttpConfiguration object as a parameter to the request 
            request.Properties.Add(HttpPropertyKeys.HttpConfigurationKey, _configuration);

            // Ensure we have a principal, even if the host didn't give us one
            IPrincipal originalPrincipal = Thread.CurrentPrincipal;
            if (originalPrincipal == null)
            {
                Thread.CurrentPrincipal = _anonymousPrincipal.Value;
            }

            return base.SendAsync(request, cancellationToken)
                       .Finally(() => Thread.CurrentPrincipal = originalPrincipal, runSynchronously: true);
        }

 这个方法整体比较简单,需要注意的地方是这里有EnsureInitialized做一些初始化工作。EnsureInitialized方法在这里调用Initialize方法,Initialize的实现很简单:

 protected virtual void Initialize()
        {
            _configuration.Initializer(_configuration);
            InnerHandler = HttpClientFactory.CreatePipeline(_dispatcher, _configuration.MessageHandlers);

        }

这里的   _configuration.Initializer的定义如下:

private Action<HttpConfiguration> _initializer = DefaultInitializer;
    public Action<HttpConfiguration> Initializer
        {
            get
            {
                return _initializer;
            }
            set
            {
                if (value == null)
                {
                    throw Error.ArgumentNull("value");
                }

                _initializer = value;
            }
        }
而DefaultInitializer方法的实现如下:

 private static void DefaultInitializer(HttpConfiguration configuration)
        {
            ModelMetadataProvider metadataProvider = configuration.Services.GetModelMetadataProvider();
            IEnumerable<ModelValidatorProvider> validatorProviders = configuration.Services.GetModelValidatorProviders();
            IRequiredMemberSelector defaultRequiredMemberSelector = new ModelValidationRequiredMemberSelector(metadataProvider, validatorProviders);


            foreach (MediaTypeFormatter formatter in configuration.Formatters)
            {
                if (formatter.RequiredMemberSelector == null)
                {
                    formatter.RequiredMemberSelector = defaultRequiredMemberSelector;
                }
            }
            ITraceManager traceManager = configuration.Services.GetTraceManager();
            Contract.Assert(traceManager != null);
            traceManager.Initialize(configuration);
        }

这个方法是很好理解的,不知道大家看到metadataProvider validatorProviders 这些变量是不是很好熟悉了(如果你已经熟悉mvc源码)。

这里的Formatters属性主要有哪些东东了,

     private readonly MediaTypeFormatterCollection _formatters = DefaultFormatters();
        public MediaTypeFormatterCollection Formatters
        {
            get { return _formatters; }
        }

        private static MediaTypeFormatterCollection DefaultFormatters()
        {
            var formatters = new MediaTypeFormatterCollection();

            // Basic FormUrlFormatter does not support binding to a T.
            // Use our JQuery formatter instead.
            formatters.Add(new JQueryMvcFormUrlEncodedFormatter());

            return formatters;
        }

让我们来看看MediaTypeFormatterCollection的构造函数吧:

public class MediaTypeFormatterCollection : Collection<MediaTypeFormatter>
{
    public MediaTypeFormatterCollection()
            : this(CreateDefaultFormatters())
        {
        }
       private static IEnumerable<MediaTypeFormatter> CreateDefaultFormatters()
        {
            return new MediaTypeFormatter[]
            {
                new JsonMediaTypeFormatter(),
                new XmlMediaTypeFormatter(),

#if !NETFX_CORE
                new FormUrlEncodedMediaTypeFormatter()
#endif
            };
        }
 

到这里我们知道Formatters主要有JsonMediaTypeFormatter,XmlMediaTypeFormatter, FormUrlEncodedMediaTypeFormatter,JQueryMvcFormUrlEncodedFormatter这4个。

在HttpServer中的Initialize方法中还有一句

  InnerHandler = HttpClientFactory.CreatePipeline(_dispatcher, _configuration.MessageHandlers);其中HttpClientFactory.CreatePipeline的实现如下:

 public static HttpMessageHandler CreatePipeline(HttpMessageHandler innerHandler, IEnumerable<DelegatingHandler> handlers)
        {
            if (innerHandler == null)
            {
                throw Error.ArgumentNull("innerHandler");
            }

            if (handlers == null)
            {
                return innerHandler;
            }


            // Wire handlers up in reverse order starting with the inner handler
            HttpMessageHandler pipeline = innerHandler;
            IEnumerable<DelegatingHandler> reversedHandlers = handlers.Reverse();
            foreach (DelegatingHandler handler in reversedHandlers)
            {
                if (handler == null)
                {
                    throw Error.Argument("handlers", Properties.Resources.DelegatingHandlerArrayContainsNullItem, typeof(DelegatingHandler).Name);
                }

                if (handler.InnerHandler != null)
                {
                    throw Error.Argument("handlers", Properties.Resources.DelegatingHandlerArrayHasNonNullInnerHandler, typeof(DelegatingHandler).Name, "InnerHandler", handler.GetType().Name);
                }

                handler.InnerHandler = pipeline;
                pipeline = handler;

            }

            return pipeline;
        }

这里的handlers是我们处理输入和输出数据的一个处理程序,有点像mvc中的filter,默认我们的handlers是没有成员的还回的还 是innerHandler,HttpServer的Initialize方法就是把_dispatcher赋给InnerHandler属性,在 HttpServer的SendAsync方法最后有这么一句:

return base.SendAsync(request, cancellationToken)
                       .Finally(() => Thread.CurrentPrincipal = originalPrincipal, runSynchronously: true);

DelegatingHandler 的SendAsync实现也很简单,主要就一句 return this.innerHandler.SendAsync(request, cancellationToken);在这里实际上就是调用HttpRoutingDispatcher的SendAsync方法。

posted on 2012-12-03 18:42  dz45693  阅读(3418)  评论(0编辑  收藏  举报

导航