您的位置:首页 > 理论基础 > 计算机网络

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

2012-12-03 18:34 567 查看
紧接着前文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方法。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: