.Net Core路由處理的知識(shí)點(diǎn)與方法總結(jié)
前言
用戶請(qǐng)求接口路由,應(yīng)用返回處理結(jié)果。應(yīng)用中如何匹配請(qǐng)求的數(shù)據(jù)呢?為何能如此精確的找到對(duì)應(yīng)的處理方法?今天就談?wù)勥@個(gè)路由。路由負(fù)責(zé)匹配傳入的HTTP請(qǐng)求,將這些請(qǐng)求發(fā)送到可以執(zhí)行的終結(jié)點(diǎn)。終結(jié)點(diǎn)在應(yīng)用中進(jìn)行定義并且在應(yīng)用啟動(dòng)的時(shí)候進(jìn)行配置,也就是在中間件中進(jìn)行處理。
路由基礎(chǔ)知識(shí)
在項(xiàng)目新建的時(shí)候都會(huì)自動(dòng)生成路由相關(guān)代碼。在Startup.Configure中的中間件管道注冊(cè)的。主要涉及到的則是UseRouting和UseEndpoints中間件。
UseRouting向中間件添加路由匹配。此中間件還會(huì)查看應(yīng)用中定義的終結(jié)點(diǎn)集。也就是把應(yīng)用中的路由統(tǒng)統(tǒng)注冊(cè)到中間件管道,方便請(qǐng)求的時(shí)候進(jìn)行匹配。
UseEndpoints向中間件添加終結(jié)點(diǎn)執(zhí)行。會(huì)運(yùn)行相關(guān)聯(lián)的委托。簡(jiǎn)單將就是路由匹配之后的處理事件運(yùn)行。
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline. public void Configure(IApplicationBuilder app, IWebHostEnvironment env) { if (env.IsDevelopment()) { app.UseDeveloperExceptionPage(); } app.UseRouting(); app.UseEndpoints(endpoints => { endpoints.MapGet("/", async context => { await context.Response.WriteAsync("Hello World!"); }); }); }
例如上面的代碼就是HTPP GET 請(qǐng)求并且Url是/的時(shí)候需要執(zhí)行的委托、如果這里的請(qǐng)求不是Get請(qǐng)求或者不是"/",那么沒有路由匹配,則會(huì)返回404。同時(shí)指定匹配模式的還有MapDelete、MapMethods、MapPost、MapPut、Map等。
終結(jié)點(diǎn)
上面講的MapGet或者未用到MapPost等就是用于定義終結(jié)點(diǎn)的。它們都包含有兩個(gè)參數(shù),一個(gè)是用于Url匹配的,另外一個(gè)就是需要執(zhí)行的委托。這里在不一樣的應(yīng)用中都采用了不同的終結(jié)點(diǎn)定義方法
- 用于 Razor Pages 的 MapRazorPages
- 用于控制器的 MapControllers
- 用于 SignalR 的 MapHub
- 用于 gRPC 的 MapGrpcService
那么我們?nèi)绻枰褂玫搅耸跈?quán)模塊將如何處理呢,終結(jié)點(diǎn)也有相對(duì)應(yīng)的處理方式。下面就展示將授權(quán)中間件和路由一起使用,MapHealthChecks添加運(yùn)行狀況檢查終結(jié)點(diǎn)。后面跟著的RequireAuthorization則是將授權(quán)策略添加到端點(diǎn)。
app.UseRouting(); app.UseAuthentication(); app.UseAuthorization(); app.UseEndpoints(endpoints => { endpoints.MapHealthChecks("/healthz").RequireAuthorization(); endpoints.MapGet("/", async context => { await context.Response.WriteAsync("Hello World!"); }); });
而且我們看中間的使用順序,UseAuthentication、UseAuthorization是穿插在UseRouting和UseEndpoints中間的,如此寫法則是為了授權(quán)策略能在UseRouting中查找終結(jié)點(diǎn),但是能在UseEndpoints發(fā)送到終結(jié)點(diǎn)執(zhí)行之前應(yīng)用所選擇的授權(quán)策略
終結(jié)點(diǎn)元數(shù)據(jù)
上面的示例展示了運(yùn)行狀況檢查終結(jié)點(diǎn)附加了授權(quán)策略。添加的授權(quán)策略是額外數(shù)據(jù),也就是終結(jié)點(diǎn)元數(shù)據(jù)。
- 可以通過路由感知中間件來處理元數(shù)據(jù)。
- 元數(shù)據(jù)可以是任意的 .NET 類型。
上面提到元數(shù)據(jù)可以是人意的.NET類型,那么具體到底是什么呢?元數(shù)據(jù)如何使用呢?
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline. public void Configure(IApplicationBuilder app, IWebHostEnvironment env) { if (env.IsDevelopment()) { app.UseDeveloperExceptionPage(); } app.UseRouting(); app.Use(next => context => { var endpoint = context.GetEndpoint(); if (endpoint?.Metadata.GetMetadata<AuditPolicyAttribute>()?.NeedsAudit ==true) { Console.WriteLine("開始處理事務(wù)邏輯"); Console.WriteLine($"ACCESS TO SENSITIVE DATA AT: {DateTime.UtcNow}"); } return next(context); }); app.UseEndpoints(endpoints => { endpoints.MapGet("/", async context => { await context.Response.WriteAsync("Hello world!"); }); // Using metadata to configure the audit policy. endpoints.MapGet("/sensitive", async context => { await context.Response.WriteAsync($"sensitive data{DateTime.UtcNow}"); }) .WithMetadata(new AuditPolicyAttribute(needsAudit: true)); }); } } public class AuditPolicyAttribute : Attribute { public AuditPolicyAttribute(bool needsAudit) { NeedsAudit = needsAudit; } public bool NeedsAudit { get; } }
看上面的示例中,在終結(jié)點(diǎn)綁定"/sensitive"的時(shí)候會(huì)附加元數(shù)據(jù)WithMetadata。當(dāng)訪問“/”的時(shí)候會(huì)輸出"Hello world!"。但是在app.Use中并不會(huì)執(zhí)行輸出"處理事務(wù)邏輯",因?yàn)椴]有匹配的元數(shù)據(jù)。但是當(dāng)執(zhí)行"/sensitive"的時(shí)候就會(huì)輸出Console.WriteLine("開始處理事務(wù)邏輯");。因?yàn)樵诮K結(jié)點(diǎn)定義的時(shí)候添加了元數(shù)據(jù)。元數(shù)據(jù)可以是人意.NET類型。上面的元數(shù)據(jù)也是我們自定義Class。
比較終端中間件和路由
上面我們使用app.Use來檢測(cè)匹配元數(shù)據(jù),如果匹配成功我們就執(zhí)行對(duì)應(yīng)的操作。我們稱之為終端中間件,為什么是終端中間件呢,因?yàn)檫@里會(huì)停止搜索執(zhí)行匹配和操作、最后返回。
那么相比較下終端中間件和路由有什么區(qū)別呢?
這兩種方法都允許終止處理管道:終端中間件允許在管道中的任意位置放置中間件:
- 中間件通過返回而不是調(diào)用 next 來終止管道。
- 終結(jié)點(diǎn)始終是終端。
終端中間件允許在管道中的任意位置放置中間件:
- 終結(jié)點(diǎn)在 UseEndpoints 位置執(zhí)行。
終端中間件允許任意代碼確定中間件匹配的時(shí)間:
- 自定義路由匹配代碼可能比較復(fù)雜,且難以正確編寫。
- 路由為典型應(yīng)用提供了簡(jiǎn)單的解決方案。
- 大多數(shù)應(yīng)用不需要自定義路由匹配代碼。
帶有中間件的終結(jié)點(diǎn)接口,如 UseAuthorization 和 UseCors。
- 通過 UseAuthorization 或 UseCors 使用終端中間件需要與授權(quán)系統(tǒng)進(jìn)行手動(dòng)交互
設(shè)置傳統(tǒng)路由
上面我們知道了通過UseRouting向中間件添加路由匹配,然后通過UseEndpoints定義終結(jié)點(diǎn)去執(zhí)行匹配委托。那么在MVC模式中如何設(shè)置呢?我們看看傳統(tǒng)路由的設(shè)置方法。
app.UseEndpoints(endpoints => { app.UseEndpoints(endpoints => { endpoints.MapControllerRoute( name: "default", pattern: "{controller=Home}/{action=Index}/{id?}"); }); });
上面我們?cè)O(shè)置傳統(tǒng)路由的時(shí)候采用的是endpoints.MapControllerRoute();,其中附帶有兩個(gè)參數(shù),一個(gè)是名稱default,第二個(gè)則是路由模板。我們看路由模板{controller=Home}/{action=Index}/{id?},那么在匹配Url路徑的時(shí)候,例如執(zhí)行路徑 WeatherForecast/Index/5。那么則會(huì)匹配控制器為WeatherForecast,其中方法是Index并且參數(shù)是int類型的一個(gè)處理方法。
REST Api 的屬性路由
上面講的是傳統(tǒng)路由設(shè)置,那么對(duì)于Api項(xiàng)目的路由設(shè)置是如何的呢?REST Api 應(yīng)使用屬性路由將應(yīng)用功能建模為一組資源。我們看下示例代碼
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline. public void Configure(IApplicationBuilder app, IWebHostEnvironment env) { if (env.IsDevelopment()) { app.UseDeveloperExceptionPage(); } app.UseRouting(); app.UseAuthorization(); app.UseEndpoints(endpoints => { endpoints.MapControllers(); }); }
在上面的代碼中使用MapControllers調(diào)用。映射屬性路由。我們看在使用的時(shí)候?qū)傩月酚傻氖褂梅绞健?/p>
Route[]
下面的示例中我們采用的是Route[]的方式,它既可單獨(dú)作用域控制器也可單獨(dú)作用域action。也可同時(shí)使用。
[ApiController] [Route("[controller]")] public class WeatherForecastController : ControllerBase { [Route("Index")] public string Index(int? id) { return "Test"; } }
[ApiController] [Route("[controller]/[action]")] public class WeatherForecastController : ControllerBase { public string Index(int? id) { return "Test"; } }
[ApiController] public class WeatherForecastController : ControllerBase { [Route("[controller]/Index")] public string Index(int? id) { return "Test"; } }
Http[Verb]
采用Http[Verb]的方式那就僅僅能作用在action上了。比如下面的就直接在Index上方寫[HttpGet
("[controller]/Index")],其他就是HttpPost、HttpDelete等等操作 [ApiController] public class WeatherForecastController : ControllerBase { [HttpGet("[controller]/Index")] public string Index(int? id) { return "Test"; } }
Route[]和Http[Verb]混合使用
有時(shí)在實(shí)際運(yùn)用中也可以采取兩種方式混合使用的,例如下面的示例在控制器采用Route[],在action采用Http[Verb]。因?yàn)橐话愣xApi的時(shí)候我們不僅要標(biāo)注action名稱,我們還需要知道action的請(qǐng)求方式。
[ApiController] [Route("[controller]")] public class WeatherForecastController : ControllerBase { [HttpGet("Index")] public string Index(int? id) { return "Test"; } }
總結(jié)
到此這篇關(guān)于.Net Core路由處理的文章就介紹到這了,更多相關(guān).Net Core路由處理內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Entity?Framework使用DBContext實(shí)現(xiàn)增刪改查
這篇文章介紹了Entity?Framework使用DBContext實(shí)現(xiàn)增刪改查的方法,文中通過示例代碼介紹的非常詳細(xì)。對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2022-10-10asp.net實(shí)現(xiàn)刪除DataGrid的記錄時(shí)彈出提示信息
這篇文章主要介紹了asp.net實(shí)現(xiàn)刪除DataGrid的記錄時(shí)彈出提示信息,非常實(shí)用的功能,需要的朋友可以參考下2014-08-08ASP.NET?MVC使用Session會(huì)話保持表單狀態(tài)
這篇文章介紹了ASP.NET?MVC使用Session會(huì)話保持表單狀態(tài)的方法,文中通過示例代碼介紹的非常詳細(xì)。對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2022-09-09Asp.net core Web Api配置swagger中文的實(shí)現(xiàn)
swagger是一個(gè)api文檔自動(dòng)生動(dòng)工具,還集成了在線調(diào)試. 可以為項(xiàng)目自動(dòng)生成接口文檔, 非常的方便快捷,具有一定的參考價(jià)值,感興趣的可以了解一下2023-09-09ADO.NET獲取數(shù)據(jù)(DataSet)同時(shí)獲取表的架構(gòu)實(shí)例
下面小編就為大家分享一篇ADO.NET獲取數(shù)據(jù)(DataSet)同時(shí)獲取表的架構(gòu)實(shí)例,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧2017-12-12顯示非站點(diǎn)目錄及映射網(wǎng)絡(luò)磁盤路徑的圖片
本文就將教你怎樣顯示非站點(diǎn)目錄下的圖片,你可以顯示站點(diǎn)所在服務(wù)器所有驅(qū)動(dòng)器目錄的圖片,以及映射網(wǎng)絡(luò)磁盤路徑的圖片,感興趣的朋友可以了解下就當(dāng)鞏固知識(shí)了或許對(duì)你學(xué)習(xí).net有所幫助2013-02-02