最新文章專題視頻專題問(wèn)答1問(wèn)答10問(wèn)答100問(wèn)答1000問(wèn)答2000關(guān)鍵字專題1關(guān)鍵字專題50關(guān)鍵字專題500關(guān)鍵字專題1500TAG最新視頻文章推薦1 推薦3 推薦5 推薦7 推薦9 推薦11 推薦13 推薦15 推薦17 推薦19 推薦21 推薦23 推薦25 推薦27 推薦29 推薦31 推薦33 推薦35 推薦37視頻文章20視頻文章30視頻文章40視頻文章50視頻文章60 視頻文章70視頻文章80視頻文章90視頻文章100視頻文章120視頻文章140 視頻2關(guān)鍵字專題關(guān)鍵字專題tag2tag3文章專題文章專題2文章索引1文章索引2文章索引3文章索引4文章索引5123456789101112131415文章專題3
問(wèn)答文章1 問(wèn)答文章501 問(wèn)答文章1001 問(wèn)答文章1501 問(wèn)答文章2001 問(wèn)答文章2501 問(wèn)答文章3001 問(wèn)答文章3501 問(wèn)答文章4001 問(wèn)答文章4501 問(wèn)答文章5001 問(wèn)答文章5501 問(wèn)答文章6001 問(wèn)答文章6501 問(wèn)答文章7001 問(wèn)答文章7501 問(wèn)答文章8001 問(wèn)答文章8501 問(wèn)答文章9001 問(wèn)答文章9501
當(dāng)前位置: 首頁(yè) - 科技 - 知識(shí)百科 - 正文

ASP.NET Core中自定義路由約束的實(shí)現(xiàn)

來(lái)源:懂視網(wǎng) 責(zé)編:小采 時(shí)間:2020-11-27 22:34:37
文檔

ASP.NET Core中自定義路由約束的實(shí)現(xiàn)

ASP.NET Core中自定義路由約束的實(shí)現(xiàn):路由約束 ASP.NET Core中,通過(guò)定義路由模板,可以在Url上傳遞變量,同時(shí)可以針對(duì)變量提供默認(rèn)值、可選和約束。 約束的使用方法是在屬性路由上添加指定的約束名,用法如下: // 單個(gè)使用 [Route(users/{id:int})] public User GetU
推薦度:
導(dǎo)讀ASP.NET Core中自定義路由約束的實(shí)現(xiàn):路由約束 ASP.NET Core中,通過(guò)定義路由模板,可以在Url上傳遞變量,同時(shí)可以針對(duì)變量提供默認(rèn)值、可選和約束。 約束的使用方法是在屬性路由上添加指定的約束名,用法如下: // 單個(gè)使用 [Route(users/{id:int})] public User GetU

路由約束

ASP.NET Core中,通過(guò)定義路由模板,可以在Url上傳遞變量,同時(shí)可以針對(duì)變量提供默認(rèn)值、可選和約束。

約束的使用方法是在屬性路由上添加指定的約束名,用法如下:

// 單個(gè)使用
[Route("users/{id:int}")]
public User GetUserById(int id) { }
// 組合使用
[Route("users/{id:int:min(1)}")]
public User GetUserById(int id) { }

框架內(nèi)部已經(jīng)提供了一些約束,如下所示:

約束 示例 匹配項(xiàng)示例 說(shuō)明
int {id:int} 123456789, -123456789 匹配任何整數(shù)
bool {active:bool} true, FALSE 匹配 true或 false(區(qū)分大小寫(xiě))
datetime {dob:datetime} 2016-12-31, 2016-12-31 7:32pm 匹配有效的 DateTime 值(位于固定區(qū)域性中 - 查看警告)
decimal {price:decimal} 49.99, -1,000.01 匹配有效的 decimal 值(位于固定區(qū)域性中 - 查看警告)
double {weight:double} 1.234, -1,001.01e8 匹配有效的 double 值(位于固定區(qū)域性中 - 查看警告)
float {weight:float} 1.234, -1,001.01e8 匹配有效的 float 值(位于固定區(qū)域性中 - 查看警告)
guid {id:guid} CD2C1638-1638-72D5-1638-DEADBEEF1638, {CD2C1638-1638-72D5-1638-DEADBEEF1638} 匹配有效的 Guid 值
long {ticks:long} 123456789, -123456789 匹配有效的 long 值
minlength(value) {username:minlength(4)} Rick 字符串必須至少為 4 個(gè)字符
maxlength(value) {filename:maxlength(8)} Richard 字符串不得超過(guò) 8 個(gè)字符
length(length) {filename:length(12)} somefile.txt 字符串必須正好為 12 個(gè)字符
length(min,max) {filename:length(8,16)} somefile.txt 字符串必須至少為 8 個(gè)字符,且不得超過(guò) 16 個(gè)字符
min(value) {age:min(18)} 19 整數(shù)值必須至少為 18
max(value) {age:max(120)} 91 整數(shù)值不得超過(guò) 120
range(min,max) {age:range(18,120)} 91 整數(shù)值必須至少為 18,且不得超過(guò) 120
alpha {name:alpha} Rick 字符串必須由一個(gè)或多個(gè)字母字符(a-z,區(qū)分大小寫(xiě))組成
regex(expression) {ssn:regex(^\d{{3}}-\d{{2}}-\d{{4}}$)} 123-45-6789 字符串必須匹配正則表達(dá)式(參見(jiàn)有關(guān)定義正則表達(dá)式的提示)
required {name:required} Rick 用于強(qiáng)制在 URL 生成過(guò)程中存在非參數(shù)值

內(nèi)置的約束能夠適用于大部分常見(jiàn)的應(yīng)用場(chǎng)景,但是有時(shí)候我們還是需要去自定義我們想要的效果。

自定義路由約束

自定義約束是要實(shí)現(xiàn) IRouteConstraint 接口,然后重載 Match 方法,該方法有四個(gè)參數(shù)。

第一個(gè)參數(shù) httpContext 是當(dāng)前請(qǐng)求的上下文

第二個(gè)參數(shù) route 是當(dāng)前約束所屬的路由

第三個(gè)參數(shù) routeKey 是當(dāng)前檢查的變量名,例如文章開(kāi)頭示例中的 id

第四個(gè)參數(shù) values 是當(dāng)前Url匹配的字典值,例如文章開(kāi)頭的示例的路由,如果Url是 users/1 ,那么就有一個(gè)字典,其 key = id , value = 1 。當(dāng)然還有其他的變量的值,比如 controller , action 等。

第五個(gè)參數(shù) routeDirection 是一個(gè)枚舉值,代表是web請(qǐng)求的還是用 Url.Action 等方法生成Url。

舉一個(gè)實(shí)例,我們想要定義一個(gè)約束,指定路由傳過(guò)來(lái)的參數(shù)必須是指定的枚舉值。

我們先定義一個(gè)枚舉:

public enum BoolEnum
{
 True,
 False
}

然后定義約束:

public class EnumConstraint : IRouteConstraint
{
 private Type _enumType;

 public EnumConstraint(string enumTypeName)
 {
 _enumType = Type.GetType(enumTypeName);
 }

 public bool Match(HttpContext httpContext, IRouter route, string routeKey, RouteValueDictionary values, RouteDirection routeDirection)
 {
 var value = values[routeKey];
 if (value == null)
 {
 return false;
 }

 if (Enum.TryParse(_enumType, value.ToString(), out object result))
 {
 if (Enum.IsDefined(_enumType, result))
 {
 return true;
 }
 }

 return false;
 }
}

在 Startup.cs 的 ConfigureServices 方法添加自定義約束:

services.Configure<RouteOptions>(options =>
{
 options.ConstraintMap.Add("enum", typeof(EnumConstraint));
});

在路由上使用約束:

( WebApplicationTest 是當(dāng)前的 namespace )

[Route("api/[controller]")]
[ApiController]
public class TestController : ControllerBase
{
 // GET: api/Test
 [HttpGet("{bool:enum(" + nameof(WebApplicationTest) + "." + nameof(BoolEnum) + ")}")]
 public string Get(BoolEnum @bool)
 {
 return "bool: " + @bool;
 }

 [HttpGet("{id:int:min(2)}", Name = "Get")]
 public string Get(int id)
 {
 return "id: " + id;
 }

 [HttpGet("{name}")]
 public string Get(string name)
 {
 return "name: " + name;
 }
}

{id:int:min(2)} 路由必須使用 min(2) ,否則對(duì)于 id = 0 或 id = 1 會(huì)有沖突。

運(yùn)行程序,當(dāng)路由是 api/Test/0 、 api/Test/1 、 api/Test/True 和 api/Test/False 的時(shí)候,匹配我們的自定義約束。

當(dāng)路由是 api/Test/{大于2的整數(shù)} 的時(shí)候,匹配第二個(gè)路由。

其他情況匹配第三個(gè)路由。

結(jié)論

路由約束在某些場(chǎng)景下是非常有用的功能,可以減少 controller 中校驗(yàn)參數(shù),將部分參數(shù)校驗(yàn)的功能使用聲明式的 attruibute 來(lái)實(shí)現(xiàn),某些重復(fù)的校驗(yàn)可以通過(guò)抽取成約束公共使用。

constraint 的構(gòu)造函數(shù)可以使用注入,所以可以擴(kuò)展性十分強(qiáng),可以通過(guò)查詢數(shù)據(jù)庫(kù)做一些參數(shù)校驗(yàn)。

官網(wǎng)上對(duì)于路由約束只是簡(jiǎn)單的提了一下,本文對(duì)路由約束的使用提供了具體的示例。

聲明:本網(wǎng)頁(yè)內(nèi)容旨在傳播知識(shí),若有侵權(quán)等問(wèn)題請(qǐng)及時(shí)與本網(wǎng)聯(lián)系,我們將在第一時(shí)間刪除處理。TEL:177 7030 7066 E-MAIL:11247931@qq.com

文檔

ASP.NET Core中自定義路由約束的實(shí)現(xiàn)

ASP.NET Core中自定義路由約束的實(shí)現(xiàn):路由約束 ASP.NET Core中,通過(guò)定義路由模板,可以在Url上傳遞變量,同時(shí)可以針對(duì)變量提供默認(rèn)值、可選和約束。 約束的使用方法是在屬性路由上添加指定的約束名,用法如下: // 單個(gè)使用 [Route(users/{id:int})] public User GetU
推薦度:
標(biāo)簽: 路由 core 約束
  • 熱門(mén)焦點(diǎn)

最新推薦

猜你喜歡

熱門(mén)推薦

專題
Top