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方法。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构