了解ASP.NET Core端点路由

原作者Areg Sarkissian

介绍

在这篇文章中,我将说明从版本2.2开始已添加到ASP.NET Core中间件管道中的新的端点路由功能,以及它如何演进到当前在预览版3的即将发布的版本3.0。

端点路由背后的动机

在端点路由之前,在HTTP请求处理管道的末尾,在ASP.NET Core MVC中间件中完成了ASP.NET Core应用程序的路由解析。这意味着在中间件管道中的MVC中间件之前,路由信息(例如将执行哪些控制器操作)对于处理请求的中间件不可用。

例如在CORS或授权中间件中提供此路由信息特别有用,以将该信息用作授权过程中的一个因素。

端点路由还允许我们将路由匹配逻辑与MVC中间件解耦,然??后将其移动到其自己的中间件中。它允许MVC中间件专注于其将请求分发到由端点路由中间件解决的特定控制器操作方法的责任。

新的端点路由中间件

由于上述原因,端点路由功能的诞生是为了使路由解析能够在单独的端点路由中间件中的管道中更早地发生。可以在管道中的任何位置放置此新的中间件,之后管道中的其他中间件可以访问已解析的路由数据。

端点路由中间件API随即将发布的.NET Core框架3.0版本一起发展。因此,我将在以下各节中描述的API可能不是该功能的最终版本。但是,总体概念和对如何使用端点路由进行路由解析和调度的理解仍然应该适用。

在以下各节中,我将引导您完成从2.2版到3.0版Preview 3的端点路由实现的当前迭代,然后我将注意到基于当前ASP.NET Core源代码的一些更改。

端点路由涉及的三个核心概念

您需要了解三个总体概念,才能理解端点路由的工作方式。

这些是以下内容:

  • 端点路由解析
  • 端点派遣
  • 端点路由映射

端点路由解析

端点路由解析是查看传入请求并将请求使用路由映射映射到端点的概念。端点表示传入请求解析的控制器操作,以及附加到与请求匹配的路由的其他元数据。

路由解析中间件的工作是使用基于路由映射解析的路由中的路由信息来构造Endpoint对象。然后,中间件将该对象放置在http上下文中,在该上下文中,在管道中的端点路由中间件可以访问端点对象并使用其中的路由信息??之后出现的其他中间件。

在端点路由之前,路由解析是在中间件管道末端的MVC中间件中完成的。该框架的当前2.2版本添加了一个新的端点路由解析中间件,该中间件可以放置在管道中的任何位置,但是将端点分发保留在MVC中间件中。这将在3.0版本中发生变化,在该版本中,终结点调度将在单独的终结点调度中间件中进行,该中间件将替换MVC中间件。

端点派遣

端点调度是调用控制器操作方法的过程,该方法对应于由端点路由中间件解析的端点。

端点分派中间件是管道中的最后一个中间件,它从http上下文中获取端点对象,并分派给解析的端点指定的特定控制器操作。

当前,在2.2版中,在管道末端的MVC中间件中完成对action方法的调度。

在3.0版预览3中,删除了MVC中间件。相反,默认情况下,端点调度发生在中间件管道的末尾。由于已删除MVC中间件,因此通常传递给MVC中间件的路由映射配置将传递给端点路由解析中间件。

根据当前的源代码,即将发布的3.0最终版本应该在管道的末尾放置一个新的端点路由中间件,以使端点再次显式分派。路由映射配置将传递到此新的中间件,而不是版本3预览版3中的端点路由解析中间件。

端点路由映射

定义路由中间件时,我们可以选择传入一个lambda函数,该函数包含的路由映射将覆盖ASP.NET Core MVC中间件扩展方法指定的默认路由映射。

路由解析过程使用路由映射将传入的请求参数与路由映射中指定的路由进行匹配。

使用新的端点路由功能,ASP.NET Core团队必须决定应使用哪个中间件(端点解析或端点调度中间件)获取路由映射配置lambda作为参数。

实际上,这是API不断变化的端点路由的一部分。在撰写本文时,路由映射已从路由解析中间件移至端点调度程序中间件。

我将首先在版本3预览3中向您展示路由映射API,然后在ASP.NET Core源代码中向您展示最新的路由映射API。在源代码版本中,我们将看到路由映射已移至端点调度程序中间件扩展方法。

重要的是要注意,在应用程序启动配置期间设置路由映射之后,端点解析会在运行时请求处理期间发生。因此,路由解析中间件可以在请求处理期间访问路由映射,而不管路由映射配置将传递到哪个中间件。

访问已解析的端点

端点路由解析中间件之后的任何中间件都将能够通过HttpContext访问已解析的端点。

以下代码段显示了如何在自己的中间件中完成此操作:

//our custom middleware
app.Use((context, next) =>
{
    var endpointFeature = context.Features[typeof(Microsoft.AspNetCore.Http.Features.IEndpointFeature)]
                                           as Microsoft.AspNetCore.Http.Features.IEndpointFeature;

    Microsoft.AspNetCore.Http.Endpoint endpoint = endpointFeature?.Endpoint;

    //Note: endpoint will be null, if there was no
    //route match found for the request by the endpoint route resolver middleware
    if (endpoint != null)
    {
        var routePattern = (endpoint as Microsoft.AspNetCore.Routing.RouteEndpoint)?.RoutePattern
                                                                                   ?.RawText;

        Console.WriteLine("Name: " + endpoint.DisplayName);
        Console.WriteLine($"Route Pattern: {routePattern}");
        Console.WriteLine("Metadata Types: " + string.Join(", ", endpoint.Metadata));
    }
    return next();
});

如您所见,我正在通过IEndpointFeature或Http Context访问已解析的终结点对象。该框架提供了包装器方法来访问终结点对象,而不必直接进入上下文,如我在此所示。

端点路由配置

中间件管道终结点路由解析器中间件,终结点调度程序中间件和终结点路由映射lambda是通过ASP.NET Core项目文件的Startup.Configure方法设置的Startup.cs

此配置在2.2和3.0 Preview 3版本之间进行了更改,并且在3.0发布版本之前仍在更改。因此,为了演示端点路由配置,我将基于上面列出的三个核心概念将端点路由中间件配置的一般形式声明为伪代码:

//psuedocode that passes route map to endpoint resolver middleware
public void Configure(IApplicationBuilder app
                     , IHostingEnvironment env)
{
    //middleware configured before the UseEndpointRouteResolverMiddleware middleware
    //that does not have access to the endpoint object
    app.UseBeforeEndpointResolutionMiddleware();

    //middleware that inspects the incoming request, resolves a match to the route map
    //and stores the resolved endpoint object into the httpcontext
    app.UseEndpointRouteResolverMiddleware(routes =>
    {
        //This is the route mapping configuration passed to the endpoint resolver middleware
        routes.MapControllers();
    })

    //middleware after configured after the UseEndpointRouteResolverMiddleware middleware
    //that can access to the endpoint object
    app.UseAfterEndpointResolutionMiddleware();

    //The middleware at the end of the pipeline that dispatches the controler action method
    //will replace the current MVC middleware
    app.UseEndpointDispatcherMiddleware();
}

此版本的伪代码显示了作为参数传递给UseEndpointRouteResolverMiddleware端点路由解析中间件扩展方法的路由映射lambda 。

匹配当前源代码的替代版本如下所示:

//psuedocode version 2 that passes route map to endpoint dispatch middleware
public void Configure(IApplicationBuilder app
                     , IHostingEnvironment env)
{
    app.UseBeforeEndpointResolutionMiddleware()

    //This is the endpoint route resolver middleware
    app.UseEndpointRouteResolverMiddleware();

    //This middleware can access the resolved endpoint object via HttpContext
    app.UseAfterEndpointResolutionMiddleware();

    //This is the endpoint dispatch middleware
    app.UseEndpointDispatcherMiddleware(routes =>
    {
        //This is the route mapping configuration passed to the endpoint dispatch middleware
        routes.MapControllers();
    });
}

在此版本中,路由映射配置作为参数传递给端点调度中间件扩展方法UseEndpointDispatcherMiddleware

无论哪种方式,UseEndpointRouteResolverMiddleware()端点解析程序中间件都可以在请求处理时访问路由映射以进行路由匹配。

一旦路由与UseEndpointRouteResolverMiddlewareEndpoint对象匹配,便将使用route参数构造并设置为httpcontext,以便后续管道中的中间件可以访问Endpoint对象并在需要时使用它。

在此伪代码的版本3预览3版本中,路由映射被传递到,UseEndpointRouteResolverMiddleware并且UseEndpointDispatcherMiddleware在管道的末尾不存在。这是因为在此版本中,ASP.NET框架本身隐式在请求管道的末尾分派了已解析的终结点。

因此,表示版本3预览版3的伪代码具有以下形式:

//pseudo code representing v3 preview 3 endpoint routing API
public void Configure(IApplicationBuilder app
                     , IHostingEnvironment env)
{
    app.UseBeforeEndpointResolutionMiddleware()

    //This is the endpoint route resolver middleware
    app.UseEndpointRouteResolverMiddleware(routes =>
    {
        //The route mapping configuration is passed to the endpoint resolution middleware
        routes.MapControllers();
    })

    //This middleware can access the resolved endpoint object via HttpContext
    app.UseAfterEndpointResolutionMiddleware()

    // The resolved endpoint is implicitly dispatched here at the end of the pipeline
    // and so there is no explicit call to a UseEndpointDispatcherMiddleware
}

该API似乎随着3.0发行版的变化而变化,因为当前的源代码显示,该API UseEndpointDispatcherMiddleware已重新添加,并且中间件将路由映射作为参数,如上面的第二版伪代码所示。

2.2版中的端点路由

如果使用.NET Core SDK版本2.2创建Web API项目,则该Startup.Configure方法中将显示以下代码:

public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
    if (env.IsDevelopment())
        app.UseDeveloperExceptionPage();
    else
        app.UseHsts();

    app.UseHttpsRedirection();

    //By default endpoint routing is not added
    //the MVC middleware dispatches the controller action
    //and the MVC middleware configures the default route mapping
    app.UseMvc();
}

使用UseMvc()扩展方法在中间件流水线的末尾配置MVC中间件。此方法在启动配置时在内部设置默认的MVC路由映射配置,并在请求处理期间调度控制器操作。

默认情况下,v2.2中的即用型模板仅配置MVC调度程序中间件。这样,MVC中间件还根据路由映射配置和传入的请求数据来处理路由解析。

但是,我们可以使用一些其他配置来添加“端点路由”,如下所示:


using Microsoft.AspNetCore.Internal;

public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
    if (env.IsDevelopment())
        app.UseDeveloperExceptionPage();
    else
        app.UseHsts();

    //added endpoint routing that will resolve the endpoint object
    app.UseEndpointRouting();

    //middleware below will have access to the Endpoint

    app.UseHttpsRedirection();

    //the MVC middleware dispatches the controller action
    //and the MVC middleware configures the default route mapping
    app.UseMvc();
}

在这里,我们添加了命名空间Microsoft.AspNetCore.Internal。包括它在内,可以启用一种附加的IApplicationBuilder扩展方法UseEndpointRouting,该方法是解决路由并将端点对象添加到httpcontext的端点解析中间件。

您可以在以下位置查看UseEndpointRouting版本2.2中扩展方法的源代码:

https://github.com/aspnet/AspNetCore/blob/v2.2.4/src/Http/Routing/src/Internal/EndpointRoutingApplicationBuilderExtensions.cs

在版本2.2中,管道末端的MVC中间件充当端点调度程序中间件。它将已解析的端点分派给适当的控制器操作。

端点解析中间件使用由MVC中间件配置的路由映射。

启用端点路由后,如果添加以下自己的自定义中间件,则可以实际检查已解析的端点对象:

using Microsoft.AspNetCore.Http.Features;
using Microsoft.AspNetCore.Routing;

public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
    if (env.IsDevelopment())
        app.UseDeveloperExceptionPage();
    else
        app.UseHsts();

    app.UseEndpointRouting();

    app.UseHttpsRedirection();

    //our custom middlware
    app.Use((context, next) =>
    {
        var endpointFeature = context.Features[typeof(IEndpointFeature)] as IEndpointFeature;
        var endpoint = endpointFeature?.Endpoint;

        //note: endpoint will be null, if there was no resolved route
        if (endpoint != null)
        {
            var routePattern = (endpoint as RouteEndpoint)?.RoutePattern
                                                          ?.RawText;

            Console.WriteLine("Name: " + endpoint.DisplayName);
            Console.WriteLine($"Route Pattern: {routePattern}");
            Console.WriteLine("Metadata Types: " + string.Join(", ", endpoint.Metadata));
        }
        return next();
    });

    app.UseMvc();
}

如您所见,我们可以检查并打印出端点路由解析中间件UseEndpointRouting已解决的端点对象 。如果解析器无法将请求匹配到映射的路由,则端点对象将为null。我们需要引入另外两个名称空间来访问端点路由功能。

版本3预览3中的端点路由

在版本3预览3中,端点路由将成为ASP.NET Core的完整公民,并且我们最终将在MVC控制器动作分派器和路由解析中间件之间实现分离。

这是版本3预览版3中的端点启动配置。

public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
    if (env.IsDevelopment())
        app.UseDeveloperExceptionPage();
    else
        app.UseHsts();

    app.UseHttpsRedirection();

    app.UseRouting(routes =>
    {
        routes.MapControllers();
    });

    app.UseAuthorization();

    //No need to have a dispatcher middleware here.
    //The resolved endpoint is automatically dispatched to a controller action at the end
    //of the middleware pipeline
    //If an endpoint was not able to be resolved, a 404 not found is returned at the end
    //of the middleware pipeline
}

如您所见,我们有一种app.UseRouting()配置端点路由解析中间件的方法。该方法还采用匿名lambda函数,该函数配置路由解析器中间件将用来解析传入请求端点的路由映射。

routes.MapControllers()映射函数内部配置默认的MVC路线。

您还将注意到,在此app.UseAuthorization()之后app.UseRouting()配置授权中间件。该中间件将有权访问由端点路由中间件设置的httpcontext端点对象。

注意,在所有其他中间件配置之后,在方法末尾我们没有配置任何MVC或端点调度中间件。

这是因为版本3预览版3的行为是,解析的终结点将由框架本身隐式分派给控制器操作。

与我们针对2.2版所做的类似,我们可以添加相同的自定义中间件来检查已解析的终结点对象。

using Microsoft.AspNetCore.Http.Features;
using Microsoft.AspNetCore.Routing;

public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
    if (env.IsDevelopment())
        app.UseDeveloperExceptionPage();
    else
        app.UseHsts();

    app.UseHttpsRedirection();

    app.UseRouting(routes =>
    {
        routes.MapControllers();
    });

    app.UseAuthorization();

    //our custom middleware
    app.Use((context, next) =>
    {
        var endpointFeature = context.Features[typeof(IEndpointFeature)] as IEndpointFeature;
        var endpoint = endpointFeature?.Endpoint;

        //note: endpoint will be null, if there was no
        //route match found for the request by the endpoint route resolver middleware
        if (endpoint != null)
        {
            var routePattern = (endpoint as RouteEndpoint)?.RoutePattern
                                                          ?.RawText;

            Console.WriteLine("Name: " + endpoint.DisplayName);
            Console.WriteLine($"Route Pattern: {routePattern}");
            Console.WriteLine("Metadata Types: " + string.Join(", ", endpoint.Metadata));
        }
        return next();
    });

    //the endpoint is dispatched by default at the end of the middleware pipeline
}

即将发布的ASP.NET Core 3.0版源代码存储库中的端点路由

当我们接近该框架的3.0版发布时,团队似乎正在通过重新添加对端点分派器中间件配置的调用来使端点路由更加明确。他们还将路由映射配置选项移回了调度程序中间件配置方法。

通过查看当前的源代码,我们可以再次看到这种变化。

以下是来自3.0版示例应用程序音乐商店的源代码的片段:

https://github.com/aspnet/AspNetCore/blob/master/src/MusicStore/samples/MusicStore/Startup.cs

public void Configure(IApplicationBuilder app)
{
    // Configure Session.
    app.UseSession();

    // Add static files to the request pipeline
    app.UseStaticFiles();

    // Add the endpoint routing matcher middleware to the request pipeline
    app.UseRouting();

    // Add cookie-based authentication to the request pipeline
    app.UseAuthentication();

    // Add the authorization middleware to the request pipeline
    app.UseAuthorization();

    // Add endpoints to the request pipeline
    app.UseEndpoints(endpoints =>
    {
        endpoints.MapControllerRoute(
            name: "areaRoute",
            pattern: "{area:exists}/{controller}/{action}",
            defaults: new { action = "Index" });

        endpoints.MapControllerRoute(
            name: "default",
            pattern: "{controller}/{action}/{id?}",
            defaults: new { controller = "Home", action = "Index" });

        endpoints.MapControllerRoute(
            name: "api",
            pattern: "{controller}/{id?}");
    });
}

如您所见,我们具有类似于我上面详细介绍的伪代码实现的东西。

特别是,我们仍然具有app.UseRouting()版本3预览版3中的 中间件设置,但是现在,我们还有一个显式的 app.UseEndpoints()终结点分发方法,该方法针对其作用更恰当地命名。

UseEndpoints是一种新的IApplicationBuilder扩展方法,提供了端点调度实现。

您可以在此处查看UseEndpointsUseRouting方法的源代码:

https://github.com/aspnet/AspNetCore/blob/master/src/Http/Routing/src/Builder/EndpointRoutingApplicationBuilderExtensions.cs

还要注意,路由映射配置lambda已从UseRouting中间件移至新的UseEndpoints中间件。

UseRouting终点的路线解析器将仍然可以访问的映射来解决在请求处理时间的终点。即使UseEndpoints在启动配置期间将它们传递到中间件。

将端点路由中间件添加到DI容器

要使用端点路由,我们还需要在该Startup.ConfigureServices方法中将中间件添加到DI容器中。

2.2版中的ConfigureServices

对于该框架的2.2版,我们需要显式添加对services.AddRouting()下面所示方法的调用,以将端点路由功能添加到DI容器:

public void ConfigureServices(IServiceCollection services)
{
    services.AddRouting()

    services.AddMvc()
            .SetCompatibilityVersion(CompatibilityVersion.Version_2_2);
}

版本3预览3中的ConfigureServices

对于版本3的预览版3框架,端点路由已经在AddMvc()扩展方法的掩盖下的DI容器中进行了配置:

public void ConfigureServices(IServiceCollection services)
{
    services.AddMvc()
            .AddNewtonsoftJson();
}

使用端点路由和路由映射设置端点授权

使用版本3 Preview 3版本时,我们可以将授权元数据附加到端点。我们使用路由映射配置流畅的API RequireAuthorization方法进行此操作。

端点路由解析器在处理请求时将访问此元数据,并将其添加到它在httpcontext上设置的Endpoint对象。

路由解析中间件之后的管道中的任何中间件都可以通过访问已解析的Endpoint对象来访问此授权数据。

特别是授权中间件可以使用此数据来做出授权决策。

当前,路由映射配置参数被传递到端点路由解析器中间件中,但是如前所述,在将来的版本中,路由映射配置将被传递到端点调度器中间件中。

无论哪种方式,附加的授权元数据都将可供端点解析器中间件使用。

以下是版本3预览3 Startup.Configure方法的示例,其中我/secret向端点解析器中间件路由映射配置lambda参数添加了新路由:

public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
    if (env.IsDevelopment())
        app.UseDeveloperExceptionPage();
    else
        app.UseHsts();

    app.UseHttpsRedirection();

    app.UseRouting(routes =>
    {
        routes.MapControllers();

        //Mapped route that gets attached authorization metadata using the RequireAuthorization extension method.
        //This metadata will be added to the resolved endpoint for this route by the endpoint resolver
        //The app.UseAuthorization() middleware later in the pipeline will get the resolved endpoint
        //for the /secret route and use the authorization metadata attached to the endpoint
        routes.MapGet("/secret", context =>
        {
            return context.Response.WriteAsync("secret");
        }).RequireAuthorization(new AuthorizeAttribute(){ Roles = "admin" });
    });

    app.UseAuthentication();

    //the Authorization middleware check the resolved endpoint object
    //to see if it requires authorization. If it does as in the case of
    //the "/secret" route, then it will authorize the route, if it the user is in the admin role
    app.UseAuthorization();

    //the framework implicitly dispatches the endpoint at the end of the pipeline.
}

您可以看到我正在使用该RequireAuthorization方法向路由添加AuthorizeAttribute属性/secret。然后,将仅由端点分发发生之前的授权中间件授权以admin角色为用户分发此路由。

正如我在3.3版预览3中所展示的那样,我们可以添加中间件来检查httpcontext中解析的终结点对象,因此我们可以在这里检查添加到终结点元数据中的AuthorizeAttribute:

using Microsoft.AspNetCore.Http.Features;
using Microsoft.AspNetCore.Routing;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Authorization;

public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
    if (env.IsDevelopment())
        app.UseDeveloperExceptionPage();
    else
        app.UseHsts();

    app.UseHttpsRedirection();

    app.UseRouting(routes =>
    {
        routes.MapControllers();

        routes.MapGet("/secret", context =>
        {
            return context.Response.WriteAsync("secret");
        }).RequireAuthorization(new AuthorizeAttribute(){ Roles = "admin" });
    });

    app.UseAuthentication();

    //our custom middleware
    app.Use((context, next) =>
    {
        var endpointFeature = context.Features[typeof(IEndpointFeature)] as IEndpointFeature;
        var endpoint = endpointFeature?.Endpoint;

        //note: endpoint will be null, if there was no
        //route match found for the request by the endpoint route resolver middleware
        if (endpoint != null)
        {
            var routePattern = (endpoint as RouteEndpoint)?.RoutePattern
                                                          ?.RawText;

            Console.WriteLine("Name: " + endpoint.DisplayName);
            Console.WriteLine($"Route Pattern: {routePattern}");
            Console.WriteLine("Metadata Types: " + string.Join(", ", endpoint.Metadata));
        }
        return next();
    });

    app.UseAuthorization();

    //the framework implicitly dispatches the endpoint here.
}

这次,我在授权中间件之前添加了自定义中间件,并引入了两个其他名称空间。

导航到/secret路线并检查元数据,您可以看到它Microsoft.AspNetCore.Authorization.AuthorizeAttribute除了类型外还包含该Microsoft.AspNetCore.Routing.HttpMethodMetadata类型。

本文使用的参考

以下文章包含了我用作本文参考的源材料:

https://devblogs.microsoft.com/aspnet/aspnet-core-3-preview-2/

https://www.stevejgordon.co.uk/asp-net-core-first-look-at-global-routing-dispatcher

vesrion 3预览版4的更新

在我发布本文的那段时间,发布了ASP.NET Core 3.0预览版4。Startup.cs创建新的webapi项目时,它添加了我在最新源代码中描述的更改,如以下文件中的代码段所示:

//code from Startup.cs file in a webapi project template

using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Http;

public void ConfigureServices(IServiceCollection services)
{
    services.AddControllers()
            .AddNewtonsoftJson();
}

public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
    if (env.IsDevelopment())
        app.UseDeveloperExceptionPage();
    else
        app.UseHsts();

    app.UseHttpsRedirection();

    //add endpoint resolution middlware
    app.UseRouting();

    app.UseAuthorization();

    //add endpoint dispatch middleware
    app.UseEndpoints(endpoints =>
    {
        //route map configuration
        endpoints.MapControllers();

        //route map I added to show Authorization setup
        endpoints.MapGet("/secret", context =>
        {
            return context.Response.WriteAsync("secret");
        }).RequireAuthorization(new AuthorizeAttribute(){ Roles = "admin" });
    });
}

如您所见,此版本UseEndpoints在添加端点调度中间件的管道的末尾添加了显式中间件扩展方法。路由配置参数也已从UseRouting预览3中的方法移动到UseEndpoints预览4中。

结论

端点路由允许ASP.NET Core应用程序在中间件管道的早期确定要调度的端点,以便以后的中间件可以使用该信息来提供当前管道配置无法提供的功能。

这使ASP.NET Core框架更加灵活,因为它使路由匹配和解析功能与终结点调度功能脱钩,而终结点调度功能迄今都与MVC中间件捆绑在一起。

本文作者:作者Areg Sarkissian

翻译至https://aregcode.com/blog/2019/dotnetcore-understanding-aspnet-endpoint-routing/

原文地址:https://www.cnblogs.com/Wadereye/p/12289237.html

时间: 2024-11-06 12:49:04

了解ASP.NET Core端点路由的相关文章

ASP.NET Core的路由[5]:内联路由约束的检验

当某个请求能够被成功路由的前提是它满足某个Route对象设置的路由规则,具体来说,当前请求的URL不仅需要满足路由模板体现的路径模式,请求还需要满足Route对象的所有约束.路由系统采用IRouteConstraint接口来表示路由约束,所以我们在接下来的内容中将路由约束统称为RouteConstraint. 在大部分情况下,约束都是针对路由模板中定义的某个路由参数,其目的在于验证URL携带的某部分的内容是否有效.不过也有一些约束与路由参数无关,这些约束规范往往是除URL之前的其他请求元素,比如

ASP.NET Core 属性路由 - ASP.NET Core 基础教程 - 简单教程,简单编程

原文:ASP.NET Core 属性路由 - ASP.NET Core 基础教程 - 简单教程,简单编程 ASP.NET Core 属性路由 经过前面章节的学习,想必你已经对 ASP.NET Core MVC 中的路由有了大概的了解,本来我想多花几章节来讲解路由规则,但是,作为基础教程,我们还是讲解下一个知识点吧. 在本章中,我们将学习另一种路由方法,即基于属性的路由. 属性路由 通过基于属性的路由,我们可以在控制器类和这些类的内部方法上使用 C# 属性. 这些属性携带了告诉 ASP.NET C

ASP.NET Core的路由[2]:路由系统的核心对象——Router

ASP.NET Core应用中的路由机制实现在RouterMiddleware中间件中,它的目的在于通过路由解析为请求找到一个匹配的处理器,同时将请求携带的数据以路由参数的形式解析出来供后续请求处理流程使用.但是具体的路由解析功能其实并没有直接实现在RouterMiddleware中间件中,而是由一个Router对象来完成的.[本文已经同步到<ASP.NET Core框架揭秘>之中] 目录一.IRouter接口二.RouteContext三.RouteData四.Route五.RouteHan

ASP.NET Core的路由[1]:注册URL模式与HttpHandler的映射关系

ASP.NET Core的路由是通过一个类型为RouterMiddleware的中间件来实现的.如果我们将最终处理HTTP请求的组件称为HttpHandler,那么RouterMiddleware中间件的意义在于实现请求路径与对应HttpHandler之间的映射关系.对于传递给RouterMiddleware中间件的每一个请求,它会通过分析请求URL的模式并选择并提取对应的HttpHandler来处理该请求.除此之外,请求的URL还会携带相应参数,该中间件在进行路由解析过程中还会根据生成相应的路

ASP.NET Core的路由[4]:来认识一下实现路由的RouterMiddleware中间件

虽然ASP.NET Core应用的路由是通过RouterMiddleware这个中间件来完成的,但是具体的路由解析功能都落在指定的Router对象上,不过我们依然有必要以代码实现的角度来介绍一下这个中间件.在这之前,我们先来认识一个特殊的特性.[本文已经同步到<ASP.NET Core框架揭秘>之中] 让RouterMiddleware中间件委托Router完整整个路由工作之后,解析出来的路由参数会以一个RouteData对象的形式存储在RouteContext上下文中.但是RouteCont

asp.net core 区域路由

Areas 提供了一种把大型 ASP.NET Core MVC Web 应用程序分为较小的功能分组的方法,用到了区域那区域路由就必不可少,下面简单实现区域路由的两种方式 1 此方式必须给控制器加上区域属性,也就是路由会自动匹配所有添加路由属性的controller 1 //路由 2 routes.MapRoute(name: "areaRoute", 3 template: "{area:exists}/{controller=MyHome}/{action=Index}&q

ASP.NET Core——网址路由

网址路由在ASP.NET MVC中有两个主要目的,分别是比对通过浏览器传来的HTTP要求与响应适当的网址给浏览器,分别描述如下. 比对通过浏览器传来的HTTP要求 这个部分是为了能让客户端对ASP.NET网站进行要求时,能够通过网址路由查找适当的HttpHandler来处理网页,大致流程图如下: 如果HttpHandler是由MvcHandler来处理,那么这时候就会进入ASP.NET MVC的运行生命周期,并且会查找适当的Controller与Action进行处理,并适当地响应消息给客户端.

.NET跨平台之旅:将示例站点从 ASP.NET 5 RC1 升级至 ASP.NET Core 1.0

终于将".NET跨平台之旅"的示例站点 about.cnblogs.com 从 ASP.NET 5 RC1 升级至 ASP.NET Core 1.0 ,经历了不少周折,在这篇博文中记录一下. 从 ASP.NET 5 到 ASP.NET Core 最大的变化,除了改名之外,就是用 dotnet cli(命令名是dotnet)取代了dnx.所以运行 ASP.NET Core 程序,首先要安装 dotnet cli,我们是在 Ubuntu 服务器上用 apt-get install dotn

【目录】ASP.NET Core 2.1 入门教程

ASP.NET Core 2.1 快速学习.入门系列教程,这个入门系列教程为了帮助大家快速上手ASP.NET Core. 本教程包含且不限于: 使用VS Code开发ASP.NET Core应用 ASP.NET Core MVC 开发(路由.控制器.视图) EF Core(连接MySQL,基础数据库操作示例) NLog日志组件使用 ASP.NET Core 中间件等等 本教程示例代码:https://github.com/ken-io/asp.net-core-tutorial https://