了解ASP.NET Core端點路由

了解ASP.NET Core端點路由

介紹

在這篇文章中但绕,我將說明從版本2.2開始已添加到ASP.NET Core中間件管道中的新的端點路由功能诊笤,以及它如何演進到當前在預覽版3的即將發(fā)布的版本3.0序苏。

端點路由背后的動機

在端點路由之前,在HTTP請求處理管道的末尾令野,在ASP.NET Core MVC中間件中完成了ASP.NET Core應用程序的路由解析。這意味著在中間件管道中的MVC中間件之前,路由信息(例如將執(zhí)行哪些控制器操作)對于處理請求的中間件不可用察蹲。

例如在CORS或授權中間件中提供此路由信息特別有用请垛,以將該信息用作授權過程中的一個因素催训。

端點路由還允許我們將路由匹配邏輯與MVC中間件解耦,然??后將其移動到其自己的中間件中宗收。它允許MVC中間件專注于其將請求分發(fā)到由端點路由中間件解決的特定控制器操作方法的責任漫拭。

新的端點路由中間件

由于上述原因,端點路由功能的誕生是為了使路由解析能夠在單獨的端點路由中間件中的管道中更早地發(fā)生混稽〔勺ぃ可以在管道中的任何位置放置此新的中間件,之后管道中的其他中間件可以訪問已解析的路由數(shù)據(jù)匈勋。

端點路由中間件API隨即將發(fā)布的.NET Core框架3.0版本一起發(fā)展礼旅。因此,我將在以下各節(jié)中描述的API可能不是該功能的最終版本洽洁。但是痘系,總體概念和對如何使用端點路由進行路由解析和調度的理解仍然應該適用。

在以下各節(jié)中饿自,我將引導您完成從2.2版到3.0版Preview 3的端點路由實現(xiàn)的當前迭代汰翠,然后我將注意到基于當前ASP.NET Core源代碼的一些更改。

端點路由涉及的三個核心概念

您需要了解三個總體概念昭雌,才能理解端點路由的工作方式复唤。

這些是以下內容:

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

端點路由解析

端點路由解析是查看傳入請求并將請求使用路由映射映射到端點的概念。端點表示傳入請求解析的控制器操作烛卧,以及附加到與請求匹配的路由的其他元數(shù)據(jù)佛纫。

路由解析中間件的工作是使用基于路由映射解析的路由中的路由信息來構造Endpoint對象。然后唱星,中間件將該對象放置在http上下文中雳旅,在該上下文中,在管道中的端點路由中間件可以訪問端點對象并使用其中的路由信息??之后出現(xiàn)的其他中間件间聊。

在端點路由之前攒盈,路由解析是在中間件管道末端的MVC中間件中完成的。該框架的當前2.2版本添加了一個新的端點路由解析中間件哎榴,該中間件可以放置在管道中的任何位置型豁,但是將端點分發(fā)保留在MVC中間件中。這將在3.0版本中發(fā)生變化尚蝌,在該版本中迎变,終結點調度將在單獨的終結點調度中間件中進行,該中間件將替換MVC中間件飘言。

端點派遣

端點調度是調用控制器操作方法的過程衣形,該方法對應于由端點路由中間件解析的端點。

端點分派中間件是管道中的最后一個中間件,它從http上下文中獲取端點對象谆吴,并分派給解析的端點指定的特定控制器操作倒源。

當前,在2.2版中句狼,在管道末端的MVC中間件中完成對action方法的調度笋熬。

在3.0版預覽3中,刪除了MVC中間件腻菇。相反胳螟,默認情況下,端點調度發(fā)生在中間件管道的末尾筹吐。由于已刪除MVC中間件糖耸,因此通常傳遞給MVC中間件的路由映射配置將傳遞給端點路由解析中間件。

根據(jù)當前的源代碼骏令,即將發(fā)布的3.0最終版本應該在管道的末尾放置一個新的端點路由中間件蔬捷,以使端點再次顯式分派。路由映射配置將傳遞到此新的中間件榔袋,而不是版本3預覽版3中的端點路由解析中間件周拐。

端點路由映射

定義路由中間件時,我們可以選擇傳入一個lambda函數(shù)凰兑,該函數(shù)包含的路由映射將覆蓋ASP.NET Core MVC中間件擴展方法指定的默認路由映射妥粟。

路由解析過程使用路由映射將傳入的請求參數(shù)與路由映射中指定的路由進行匹配。

使用新的端點路由功能吏够,ASP.NET Core團隊必須決定應使用哪個中間件(端點解析或端點調度中間件)獲取路由映射配置lambda作為參數(shù)勾给。

實際上,這是API不斷變化的端點路由的一部分锅知。在撰寫本文時播急,路由映射已從路由解析中間件移至端點調度程序中間件。

我將首先在版本3預覽3中向您展示路由映射API售睹,然后在ASP.NET Core源代碼中向您展示最新的路由映射API桩警。在源代碼版本中,我們將看到路由映射已移至端點調度程序中間件擴展方法昌妹。

重要的是要注意捶枢,在應用程序啟動配置期間設置路由映射之后,端點解析會在運行時請求處理期間發(fā)生飞崖。因此烂叔,路由解析中間件可以在請求處理期間訪問路由映射,而不管路由映射配置將傳遞到哪個中間件固歪。

訪問已解析的端點

端點路由解析中間件之后的任何中間件都將能夠通過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發(fā)布版本之前仍在更改辜伟。因此,為了演示端點路由配置脊另,我將基于上面列出的三個核心概念將端點路由中間件配置的一般形式聲明為偽代碼:

//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();
}

此版本的偽代碼顯示了作為參數(shù)傳遞給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();
    });
}

在此版本中,路由映射配置作為參數(shù)傳遞給端點調度中間件擴展方法UseEndpointDispatcherMiddleware偎痛。

無論哪種方式旱捧,UseEndpointRouteResolverMiddleware()端點解析程序中間件都可以在請求處理時訪問路由映射以進行路由匹配。

一旦路由與UseEndpointRouteResolverMiddlewareEndpoint對象匹配踩麦,便將使用route參數(shù)構造并設置為httpcontext枚赡,以便后續(xù)管道中的中間件可以訪問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發(fā)行版的變化而變化才顿,因為當前的源代碼顯示莫湘,該API UseEndpointDispatcherMiddleware已重新添加,并且中間件將路由映射作為參數(shù)郑气,如上面的第二版?zhèn)未a所示幅垮。

2.2版中的端點路由

如果使用.NET Core SDK版本2.2創(chuàng)建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中間件還根據(jù)路由映射配置和傳入的請求數(shù)據(jù)來處理路由解析爷耀。

但是甘桑,我們可以使用一些其他配置來添加“端點路由”,如下所示:


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中間件充當端點調度程序中間件。它將已解析的端點分派給適當?shù)目刂破鞑僮鳌?/p>

端點解析中間件使用由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控制器動作分派器和路由解析中間件之間實現(xiàn)分離盆偿。

這是版本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函數(shù),該函數(shù)配置路由解析器中間件將用來解析傳入請求端點的路由映射兄裂。

routes.MapControllers()映射函數(shù)內部配置默認的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
}

即將發(fā)布的ASP.NET Core 3.0版源代碼存儲庫中的端點路由

當我們接近該框架的3.0版發(fā)布時豹爹,團隊似乎正在通過重新添加對端點分派器中間件配置的調用來使端點路由更加明確裆悄。他們還將路由映射配置選項移回了調度程序中間件配置方法。

通過查看當前的源代碼臂聋,我們可以再次看到這種變化光稼。

以下是來自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?}");
    });
}

如您所見或南,我們具有類似于我上面詳細介紹的偽代碼實現(xiàn)的東西。

特別是艾君,我們仍然具有app.UseRouting()版本3預覽版3中的 中間件設置采够,但是現(xiàn)在,我們還有一個顯式的 app.UseEndpoints()終結點分發(fā)方法冰垄,該方法針對其作用更恰當?shù)孛?/p>

UseEndpoints是一種新的IApplicationBuilder擴展方法蹬癌,提供了端點調度實現(xiàn)。

您可以在此處查看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框架尼啡,端點路由已經(jīng)在AddMvc()擴展方法的掩蓋下的DI容器中進行了配置:

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

使用端點路由和路由映射設置端點授權

使用版本3 Preview 3版本時暂衡,我們可以將授權元數(shù)據(jù)附加到端點。我們使用路由映射配置流暢的API RequireAuthorization方法進行此操作崖瞭。

端點路由解析器在處理請求時將訪問此元數(shù)據(jù)狂巢,并將其添加到它在httpcontext上設置的Endpoint對象。

路由解析中間件之后的管道中的任何中間件都可以通過訪問已解析的Endpoint對象來訪問此授權數(shù)據(jù)书聚。

特別是授權中間件可以使用此數(shù)據(jù)來做出授權決策唧领。

當前,路由映射配置參數(shù)被傳遞到端點路由解析器中間件中雌续,但是如前所述斩个,在將來的版本中,路由映射配置將被傳遞到端點調度器中間件中驯杜。

無論哪種方式受啥,附加的授權元數(shù)據(jù)都將可供端點解析器中間件使用。

以下是版本3預覽3 Startup.Configure方法的示例鸽心,其中我/secret向端點解析器中間件路由映射配置lambda參數(shù)添加了新路由:

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滚局。然后,將僅由端點分發(fā)發(fā)生之前的授權中間件授權以admin角色為用戶分發(fā)此路由顽频。

正如我在3.3版預覽3中所展示的那樣藤肢,我們可以添加中間件來檢查httpcontext中解析的終結點對象,因此我們可以在這里檢查添加到終結點元數(shù)據(jù)中的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路線并檢查元數(shù)據(jù),您可以看到它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的更新

在我發(fā)布本文的那段時間冀宴,發(fā)布了ASP.NET Core 3.0預覽版4。Startup.cs創(chuàng)建新的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在添加端點調度中間件的管道的末尾添加了顯式中間件擴展方法仗岖。路由配置參數(shù)也已從UseRouting預覽3中的方法移動到UseEndpoints預覽4中逃延。

結論

端點路由允許ASP.NET Core應用程序在中間件管道的早期確定要調度的端點,以便以后的中間件可以使用該信息來提供當前管道配置無法提供的功能轧拄。

這使ASP.NET Core框架更加靈活揽祥,因為它使路由匹配和解析功能與終結點調度功能脫鉤,而終結點調度功能迄今都與MVC中間件捆綁在一起檩电。

翻譯至:
https://aregcode.com/blog/2019/dotnetcore-understanding-aspnet-endpoint-routing/
原作者:Areg Sarkissian

?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末拄丰,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子俐末,更是在濱河造成了極大的恐慌料按,老刑警劉巖,帶你破解...
    沈念sama閱讀 206,214評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件卓箫,死亡現(xiàn)場離奇詭異载矿,居然都是意外死亡,警方通過查閱死者的電腦和手機烹卒,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,307評論 2 382
  • 文/潘曉璐 我一進店門闷盔,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人旅急,你說我怎么就攤上這事馁筐。” “怎么了坠非?”我有些...
    開封第一講書人閱讀 152,543評論 0 341
  • 文/不壞的土叔 我叫張陵敏沉,是天一觀的道長。 經(jīng)常有香客問我炎码,道長盟迟,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 55,221評論 1 279
  • 正文 為了忘掉前任潦闲,我火速辦了婚禮攒菠,結果婚禮上,老公的妹妹穿的比我還像新娘歉闰。我一直安慰自己辖众,他們只是感情好卓起,可當我...
    茶點故事閱讀 64,224評論 5 371
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著凹炸,像睡著了一般戏阅。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上啤它,一...
    開封第一講書人閱讀 49,007評論 1 284
  • 那天奕筐,我揣著相機與錄音,去河邊找鬼变骡。 笑死离赫,一個胖子當著我的面吹牛,可吹牛的內容都是我干的塌碌。 我是一名探鬼主播渊胸,決...
    沈念sama閱讀 38,313評論 3 399
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼台妆!你這毒婦竟也來了翎猛?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 36,956評論 0 259
  • 序言:老撾萬榮一對情侶失蹤频丘,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后泡态,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體搂漠,經(jīng)...
    沈念sama閱讀 43,441評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 35,925評論 2 323
  • 正文 我和宋清朗相戀三年某弦,在試婚紗的時候發(fā)現(xiàn)自己被綠了桐汤。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 38,018評論 1 333
  • 序言:一個原本活蹦亂跳的男人離奇死亡靶壮,死狀恐怖怔毛,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情腾降,我是刑警寧澤拣度,帶...
    沈念sama閱讀 33,685評論 4 322
  • 正文 年R本政府宣布,位于F島的核電站螃壤,受9級特大地震影響抗果,放射性物質發(fā)生泄漏。R本人自食惡果不足惜奸晴,卻給世界環(huán)境...
    茶點故事閱讀 39,234評論 3 307
  • 文/蒙蒙 一冤馏、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧寄啼,春花似錦逮光、人聲如沸代箭。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,240評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽嗡综。三九已至,卻和暖如春副女,著一層夾襖步出監(jiān)牢的瞬間蛤高,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,464評論 1 261
  • 我被黑心中介騙來泰國打工碑幅, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留戴陡,地道東北人。 一個月前我還...
    沈念sama閱讀 45,467評論 2 352
  • 正文 我出身青樓沟涨,卻偏偏與公主長得像恤批,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子裹赴,可洞房花燭夜當晚...
    茶點故事閱讀 42,762評論 2 345

推薦閱讀更多精彩內容