tft每日頭條

 > 圖文

 > net core 詳解

net core 詳解

圖文 更新时间:2024-07-04 06:45:35

前言

路由,這詞絕對不陌生,不管在前端還是後端都經常提到,而這節不說其他,就聊.NetCore的路由;在之前的http://Asp.Net MVC 中,路由算是面試時必問的考點,可見其重要性,它的主要作用是映射URL,而不需要關注服務器的物理文件結構,提高安全性,同時規範了URL請求,有利于搜索引擎優化;所以在Asp.NetCore中當然也不能缺少,以下說說其應用。

正文

在Asp.NetCore中,注冊路由方式有兩種:

  • 模闆路由注冊:适合應用于MVC頁面項目,相對于來說,使用模闆的形式更加方便,約定大于配置,統一URL;
  • 特性路由注冊(RouteAttribute):适合應用于API項目,針對于不同業務路由會進行定制,特性标注顯得更加便捷;

少說話,多撸碼,這裡就創建一個WebAPI項目來進行演示:

net core 詳解(17-跟我一起學.NetCore之路由的最佳實現)1

默認情況下,創建的WebAPI項目是推薦使用特性路由方式進行注冊(MVC默認是使用路由模闆方式),當然也可以在Api項目中進行使用模闆路由方式注冊,如下:

net core 詳解(17-跟我一起學.NetCore之路由的最佳實現)2

當注釋掉特性路由,在注冊終結點時增加路由模闆,最終運行時會出現異常,因為用ApiController标識的Controller必須是特性路由,那把ApiController特性也注釋掉,結果就正常運行了,如下:

net core 詳解(17-跟我一起學.NetCore之路由的最佳實現)3

這裡其實有一個重要的知識點:路由匹配規則,考慮到小夥伴們之前使用http://Asp.Net MVC時就用到,先默認小夥伴們了解這塊知識(抽時間單獨整理一篇出來);以下内容着重說說特性路由應用和路由約束這塊,因為有關注到接觸的項目中不管是之前的http://Asp.Net, 還是現在的Asp.NetCore項目,幾乎沒有看到路由約束的應用,而在很多場景,路由約束很有必要,用于消除路由的歧義。

特性路由應用

直接在Action上加Route 特性,如下:

net core 詳解(17-跟我一起學.NetCore之路由的最佳實現)4

運行結果如下:

net core 詳解(17-跟我一起學.NetCore之路由的最佳實現)5

通常為了避免在每個Action中的重複的指定路徑前綴,可以将公共部分提取到Controller類上進行Route标識,如下:

net core 詳解(17-跟我一起學.NetCore之路由的最佳實現)6

統一前綴之後,運行結果:

net core 詳解(17-跟我一起學.NetCore之路由的最佳實現)7

以上的方式都是将路徑寫成固定的字符串,有時候會要求像模闆路由中那樣動态替換指定标記([area],[controller],[action] ),通常項目中會如下使用:

net core 詳解(17-跟我一起學.NetCore之路由的最佳實現)8

以上隻是簡單說說特性路由的用法,小夥伴們可以根據實際情況進行标注,當然如果有特殊需求,也可以進行自定義路由特性,隻要繼承IRouteTemplateProvider接口即可,上面标注的Route和HttpGet特性也是繼承于這個接口,把RouteAtrribute的源代碼扒出來參考參考:

namespace Microsoft.AspNetCore.Mvc { // 标識此特性隻能在類和方法上使用 [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = true, Inherited = true)] public class RouteAttribute : Attribute, IRouteTemplateProvider { private int? _order; // 構造函數,傳入一個Url模闆參數 public RouteAttribute(string template) { Template = template ?? throw new ArgumentNullException(nameof(template)); } public string Template { get; } // 路由執行順序,默認為0 public int Order { get { return _order ?? 0; } set { _order = value; } } /// <inheritdoc /> int? IRouteTemplateProvider.Order => _order; // 路由名稱,後續可以根據路由名稱生成Url,而不是硬編碼編寫 public string Name { get; set; } } }

來,自己也搞一個特性路由練練:

net core 詳解(17-跟我一起學.NetCore之路由的最佳實現)9

有沒有很簡單,其實這裡是忍住沒去扒代碼的,後續單獨去扒;用法就先暫時說這麼多,接下來說說路由傳參和約束。

路由傳參和約束

一般情況,會針對路由中動态參數進行約束;從而路由約束可能會被作為輸入校驗,但是官方不推薦,因為當規則不匹配的時候,返回狀态404(找不到),而事實對應地址可以到達請求,隻是參數輸入不合法而已,所以官方推薦作為消除路由歧義 ,同時也能避免不規則的路由進行業務處理;直接來案例演示(廢話多了怕掉坑裡):

net core 詳解(17-跟我一起學.NetCore之路由的最佳實現)10

新增的Controller完整代碼:

namespace RouteDemo.Controllers { [ApiController] [Route("/api/[controller]")] public class TestConstraintController { /// <summary> /// 驗證必須輸入,沒有輸入就返回404 /// </summary> [HttpGet("TestRequiredConstraint/{name:required}")] public string TestRequiredConstraint(string name) { return "TestRequiredConstraint"; } /// <summary> /// 整型約束,非整型數據就返回404 /// </summary> [HttpGet("TestValueConstraint/{id:int}")] public string TestValueConstraint(int id) { return "TestValueConstraint"; } /// <summary> /// 傳入最小值為100,傳入值小于100就返回404 /// </summary> [HttpGet("TestMinConstraint/{id:min(100)}")] public string TestMinConstraint(int id) { return "TestMinConstraint"; } /// <summary> /// 範圍約束8到18,不在這個範圍内就返回404 /// </summary> [HttpGet("TestRangeConstraint/{id:range(8,18)}")] public string TestRangeConstraint(int id) { return "TestRangConstraint"; } /// <summary> /// 驗證最小長度為5,低于這個長度就返回404 /// </summary> [HttpGet("TestMinLengthConstraint/{name:minLength(5)}")] public string TestMinLengthConstraint(string name) { return "TestMinLengthConstraint"; } /// <summary> /// 正則表達式約束,以三個數字開頭,不滿足就返回404 /// </summary> [HttpGet("TestRegexConstraint/{msg:regex(^\\d{{3}})}")] public string TestRegexConstraint(string msg) { return "TestRegexConstraint"; } /// <summary> /// 整型約束,範圍約束8到18,不在這個範圍内就返回404 /// </summary> [HttpGet("TestMultiConstraint/{id:int:range(8,18)}")] public string TestMultiConstraint(int id) { return "TestRangConstraint"; } } }

以上隻是挑了幾個默認内置的約束進行舉例演示,其實還有很多,剩下的小夥伴下來一定要試試,用法都很簡單,如下:

  • 單個約束時

參數:約束

案例:[HttpGet("TestRequiredConstraint/{name:required}")]

  • 多個約束時

參數:約束1:約束2:....

案例:[HttpGet("TestMultiConstraint/{id:int:range(8,18)}")]

框架本身内置的約束,如下(小夥伴一定要敲敲):

net core 詳解(17-跟我一起學.NetCore之路由的最佳實現)11

不用說,内置約束肯定不可能面面俱到,所以針對個性化約束,還需要自定義,繼承 IRouteConstraint 接口便可實現自定義路由約束。 接口中包含 Match,當滿足約束時,它返回 true,否則返回 false。如下例演示:

net core 詳解(17-跟我一起學.NetCore之路由的最佳實現)12

net core 詳解(17-跟我一起學.NetCore之路由的最佳實現)13

總結

特性路由和約束就說到這吧,根據實際需求進行路由約束,但不能盲目,如果是要進行輸入數據校驗,請考慮使用模型驗證!下一節說說集成Swagger。

感謝小夥伴的:點贊收藏評論,下期繼續~~~

一個被程序搞醜的帥小夥,關注"Code綜藝圈",跟我一起學~~~

,

更多精彩资讯请关注tft每日頭條,我们将持续为您更新最新资讯!

查看全部

相关圖文资讯推荐

热门圖文资讯推荐

网友关注

Copyright 2023-2024 - www.tftnews.com All Rights Reserved