ITKeyword,专注技术干货聚合推荐

注册 | 登录

ASP.NET Web API :Web宿主

分享于

2021腾讯云限时秒杀,爆款1核2G云服务器298元/3年!(领取2860元代金券),
地址https://cloud.tencent.com/act/cps/redirect?redirect=1062

2021阿里云最低价产品入口+领取代金券(老用户3折起),
入口地址https://www.aliyun.com/minisite/goods

推荐:使用OWIN 构建自宿主ASP.NET Web API 2

--Use OWIN to Self-Host ASP.NET Web API 2 原文链接:http://www.asp.net/web-api/overview/hosting-aspnet-web-api/use-owin-to-self-host-web-api 摘要:ASP

上一节描述了API的整个运行框架,即分为三层hosting、message handler pipeline 和 controller handling。此节讲其中一个宿主,WebHost 寄宿在asp.net 传统管道上。

Routing(路由)

在asp.net平台,路由是一般由RouteTables.Routes静态属性添加的,类型是RouteCollection,例如下面的MVC模板自带的添加路由的代码。

protected void Application_Start()
{
    RegisterRoutes(RouteTable.Routes);
}
  
public static void RegisterRoutes(RouteCollection routes)
{
    routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
  
    routes.MapRoute(
        "Default", // Route name
        "{controller}/{action}/{id}", // URL with parameters
        new { controller = "Home", action = "Index", id = UrlParameter.Optional } 
    );
}

大部分路由逻辑都是在UrlRoutingModule里,属于PostResolveRequestCache asp.net管道事件。每一次请求,这个module都是重新匹配一次这个路由集合,并获取一个RouteData实例,如果匹配,则:

1、实例化RouteData同时获取一个route handler(HttpControllerRouteHandler)。

2、从routehandler获取一个http handle 继承自IHttphandler接口。IRouteHandler接口方法:IHttpHandler GetHttpHandler(RequestContext requestContext)

3、最后,当前的请求上下文(RequestContext)被映射到上面的这个httphandler。

因此,最后结果是asp.net管道请求被此handler处理。

Web API 集成

当寄宿在asp.net上,Web API特定的配置被定义在一个单例模式的HttpConfiguration对象里,通过静态属性GlobalCnfiguration.Configuration访问。

Web API 也定义了一对新的RouteCollection扩展方法MapHttpRoute,来注册Web API特殊的路由,下面是配置的例子代码:

HttpConfiguration config = GlobalConfiguration.Configuration;
config.Routes.MapHttpRoute("default", "{controller}/{id}",  new {id = UrlParameter.Optional});
// other configuration settings

注意:

  1. 静态属性GlobalConfiguration.Configuration是用于获取配置的引用,内部这个对象指向的是全局的RouteTables.Routes这个集合。
  2. 当新增路由时使用的是MapHttpRoute这个扩展方法。

当一个route通过MapHttpRoute增加后匹配到一个Request,,HttpControllerRouteHandler会创建一个新的HttpControllerHandler,其继承自IAsyncHttpHandler,此handler通过RouteData(包含了路由的信息)初始化。

当被调用,HttpControllerhandler 在他的BeginReocessRequest方法里有以下行为:

  • 为当前上下文创建HttpRequestMessage实例
  • 使用GlobalConfiguration.Configuration获取配置并创建一个HttpServer,并且把HttpRequestMessage送入服务管道。

当这个请求被HttpServer接受后,进入宿主的独立处理阶段(Web API的新管道)

推荐:asp.net web api

官方的地址: http://www.asp.net/web-api 里面的资料很全,是学习的第一选择.建议多参考此资料 1.里面最简单直接的例子 http://www.asp.net/web-api/overview/get

下面的类图是路由解决过程的摘要,并且分配给HttpServer(消息处理管道)

 

原文地址: 

ASP.NET Web API: web hosting

 

看文字描述比较晦涩难懂,需要根据源码理解,上图容易理解。

HttpApplication -> UrlRoutingModule -> RouteCollection -> RouteData -> HttpControllerRouteHandler -> HttpControllerHandler -> HttpRequestMessage -> HttpServer

附加一些源码:
1、UrlRoutingModule获取RouteData

public virtual void PostResolveRequestCache(HttpContextBase context)
{
    RouteData routeData = this.RouteCollection.GetRouteData(context);
    if (routeData == null)
    {
        return;
    }
    IRouteHandler routeHandler = routeData.RouteHandler;
    if (routeHandler == null)
    {
        throw new InvalidOperationException(string.Format(CultureInfo.CurrentCulture, SR.GetString("UrlRoutingModule_NoRouteHandler"), new object[0]));
    }
    if (routeHandler is StopRoutingHandler)
    {
        return;
    }
    RequestContext requestContext = new RequestContext(context, routeData);
    context.Request.RequestContext = requestContext;
    IHttpHandler httpHandler = routeHandler.GetHttpHandler(requestContext);
    if (httpHandler == null)
    {
        throw new InvalidOperationException(string.Format(CultureInfo.CurrentUICulture, SR.GetString("UrlRoutingModule_NoHttpHandler"), new object[]
        {
            routeHandler.GetType()
        }));
    }
    if (!(httpHandler is UrlAuthFailureHandler))
    {
        context.RemapHandler(httpHandler);
        return;
    }
    if (FormsAuthenticationModule.FormsAuthRequired)
    {
        UrlAuthorizationModule.ReportUrlAuthorizationFailure(HttpContext.Current, this);
        return;
    }
    throw new HttpException(401, SR.GetString("Assess_Denied_Description3"));
}

2、MapHttpRoute(RouteCollectionExtension)

public static Route MapHttpRoute(this RouteCollection routes, string name, string routeTemplate, object defaults, object constraints, HttpMessageHandler handler)
{
    if (routes == null)
    {
        throw Error.ArgumentNull("routes");
    }

    HttpRouteValueDictionary defaultsDictionary = new HttpRouteValueDictionary(defaults);
    HttpRouteValueDictionary constraintsDictionary = new HttpRouteValueDictionary(constraints);
    HostedHttpRoute httpRoute = (HostedHttpRoute)GlobalConfiguration.Configuration.Routes.CreateRoute(routeTemplate, defaultsDictionary, constraintsDictionary, dataTokens: null, handler: handler);
    Route route = httpRoute.OriginalRoute;
    routes.Add(name, route);
    return route;
}

3、HttpControllerRouteHandler.GetHandler

protected virtual IHttpHandler GetHttpHandler(RequestContext requestContext)
{
    return new HttpControllerHandler(requestContext.RouteData);
}

4、HttpControllerHandler.ProcessRequest

internal async Task ProcessRequestAsyncCore(HttpContextBase contextBase)
{
    HttpRequestMessage request = contextBase.GetHttpRequestMessage() ?? ConvertRequest(contextBase);

    // Add route data
    request.SetRouteData(_routeData);
    CancellationToken cancellationToken = contextBase.Response.GetClientDisconnectedTokenWhenFixed();
    HttpResponseMessage response = null;

    try
    {
        response = await _server.SendAsync(request, cancellationToken);
        await CopyResponseAsync(contextBase, request, response, _exceptionLogger.Value, _exceptionHandler.Value,
            cancellationToken);
    }
    finally
    {
        // The other HttpTaskAsyncHandler is HttpRouteExceptionHandler; it has similar cleanup logic.
        request.DisposeRequestResources();
        request.Dispose();

        if (response != null)
        {
            response.Dispose();
        }
    }
}

5、HttpApplication -> HttpControllerHandler

public HttpControllerHandler(RouteData routeData)
    : this(routeData, GlobalConfiguration.DefaultServer)//HttpServer : DelegatingHandler : HttpMessageHandler
{
}

public HttpControllerHandler(RouteData routeData, HttpMessageHandler handler)
{
    if (routeData == null)
    {
        throw Error.ArgumentNull("routeData");
    }
    if (handler == null)
    {
        throw Error.ArgumentNull("handler");
    }

    _routeData = new HostedHttpRouteData(routeData);
    _server = new HttpMessageInvoker(handler);
}




推荐:ASP.NET Web API

ASP.NET Web API includes support for the following features: Modern HTTP programming model: Directly access and manipulate HTTP requests and responses

上一节描述了API的整个运行框架,即分为三层hosting、message handler pipeline 和 controller handling。此节讲其中一个宿主,WebHost 寄宿在asp.net 传统管道上。 Routing(路由) 在asp.net

相关阅读排行


相关内容推荐

最新文章

×

×

请激活账号

为了能正常使用评论、编辑功能及以后陆续为用户提供的其他产品,请激活账号。

您的注册邮箱: 修改

重新发送激活邮件 进入我的邮箱

如果您没有收到激活邮件,请注意检查垃圾箱。