zoukankan      html  css  js  c++  java
  • 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方法。

  • 相关阅读:
    html5和html4.0.1的<html>标记的区别
    javascript 在页面不刷新的情况下 其中的变量时不会被初始化的
    Spring配置项<context:annotation-config/>解释说明
    阿里负责人揭秘面试潜规则
    Ubuntu 软件安装、查找、卸载--apt-get、apt-cache命令安全
    Spring 中 ApplicationContext 、WebApplicationContext 和 BeanFactory 比较
    [Spring3.x] 第 15 章 Spring MVC : 第 四 篇 业务层及 web 层技术开发
    [Spring3.x] 第 11 章 使用 Spring JDBC 访问数据库 & 第 12 章 整合其他 ORM 框架
    [Spring3.x] 第 8 章 Spring 对 DAO 的支持
    [Spring3.x] 第 3 章 IOC 容器概述
  • 原文地址:https://www.cnblogs.com/majiang/p/2800147.html
Copyright © 2011-2022 走看看