這篇文章主要為大家展示了“ASP.NET Core MVC之路由的示例分析”,內(nèi)容簡(jiǎn)而易懂,條理清晰,希望能夠幫助大家解決疑惑,下面讓小編帶領(lǐng)大家一起研究并學(xué)習(xí)一下“ASP.NET Core MVC之路由的示例分析”這篇文章吧。
創(chuàng)新互聯(lián)建站是專(zhuān)業(yè)的忻府網(wǎng)站建設(shè)公司,忻府接單;提供成都網(wǎng)站設(shè)計(jì)、成都做網(wǎng)站,網(wǎng)頁(yè)設(shè)計(jì),網(wǎng)站設(shè)計(jì),建網(wǎng)站,PHP網(wǎng)站建設(shè)等專(zhuān)業(yè)做網(wǎng)站服務(wù);采用PHP框架,可快速的進(jìn)行忻府網(wǎng)站開(kāi)發(fā)網(wǎng)頁(yè)制作和功能擴(kuò)展;專(zhuān)業(yè)做搜索引擎喜愛(ài)的網(wǎng)站,專(zhuān)業(yè)的做網(wǎng)站團(tuán)隊(duì),希望更多企業(yè)前來(lái)合作!前言
ASP.NET Core MVC 路由是建立在ASP.NET Core 路由的,一項(xiàng)強(qiáng)大的URL映射組件,它可以構(gòu)建具有理解和搜索網(wǎng)址的應(yīng)用程序。這使得我們可以自定義應(yīng)用程序的URL命名形式,使得它在搜索引擎優(yōu)化(SEO)和鏈接生成中運(yùn)行良好,而不用關(guān)心Web服務(wù)器上的文件是怎么組織的。我們可以方便的使用路由模板語(yǔ)法定義路由,路由模板語(yǔ)法支持路由值約束,默認(rèn)值和可選值。
基于約束的路由允許全局定義應(yīng)用支持的URL格式,以及這些格式是怎樣各自在給定的控制器中映射到指定的操作方法(Action)。當(dāng)接受到一個(gè)請(qǐng)求時(shí),路由引擎解析URL并將其匹配至一個(gè)定義URL格式,然后調(diào)用相關(guān)的控制器操作方法?!?/p>
routes.MapRoute( name: "default", template: "{controller=Home}/{action=Index}/{id?}");
特性路由(Attribute Routing) 允許以在控制器和方法使用添加特性的方式指定路由信息來(lái)定義應(yīng)用程序的路由。這意味著路由定義緊鄰它們所關(guān)聯(lián)的控制器和方法。
ASP.NET Core MVC 使用路由中間件來(lái)匹配傳入請(qǐng)求的URL,并將它們映射到操作方法。路由在啟動(dòng)代碼或?qū)傩灾卸x,它描述了網(wǎng)址路徑應(yīng)如何與操作方法匹配,還用于響應(yīng)中生成鏈接并發(fā)送。
1.設(shè)置路由中間件
創(chuàng)建一個(gè)ASP.NET Core Web應(yīng)用程序,在Startup類(lèi)的Configure方法中有:
app.UseMvc(routes => { routes.MapRoute( name: "default", template: "{controller=Home}/{action=Index}/{id?}"); });
在對(duì)UseMvc的調(diào)用過(guò)程中,MapRoute用于創(chuàng)建單個(gè)路由,即默認(rèn)路由。大多數(shù)MVC應(yīng)用程序都使用與默認(rèn)路由模板類(lèi)似的路由。
路由模板{controller=Home}/{action=Index}/{id?}
可以匹配類(lèi)似 Blog/Details/5 的URL路徑,并且提取路由值{controller=Blog,action=Details,id=5}
。MVC將嘗試查找名為BlogController的控制器,并運(yùn)行操作方法。
{controller=Home}
將Home定義為默認(rèn)控制器
{action=Index}
將Index定義為默認(rèn)操作
{id?}將id定義為可選
默認(rèn)路徑參數(shù)和可選路徑參數(shù)可以不出現(xiàn)在需要匹配的URL路徑中。
使用{controller=Home}/{action=Index}/{id?}
模板,可以對(duì)以下URL路徑都執(zhí)行HomeController.Index:
/Home/Index/7
/Home/Index
/Home
/
有個(gè)簡(jiǎn)單方法app.UseMvcWithDefaultRoute()
可以替換掉上面的方法。
UseMvc 和 UseMvcWithDefaultRoute 都是將RouteMiddleware的實(shí)例添加到中間件管道。MVC不直接與中間件交互,而是使用路由來(lái)處理請(qǐng)求。MVC通過(guò)MvcRouteHandler的實(shí)例鏈接到路由。下面的代碼與UseMvc類(lèi)似:
var route = new RouteBuilder(app); //添加連接到MVC,通過(guò)調(diào)用MapRoute來(lái)回調(diào) route.DefaultHandler = new MvcRouteHandler(...); //執(zhí)行回調(diào)以注冊(cè)路由 route.MapRoute("default", "{controller=Home}/{action=Index}/{id?}"); //創(chuàng)建路由集合并添加至中間件 app.UseRouter(route.Build());
UseMvc 不直接定義任何路由,它為屬性路由的路由集合添加一個(gè)占位符。重載UseMvc 使得我們可以添加自己的路由,并且還支持屬性路由。UseMvc 及其所有變體為屬性路由添加了占位符,這使得屬性路由始終可用。UseMvcWithDefaultRoute定義默認(rèn)路由并且支持屬性路由。
2.常規(guī)路由
routes.MapRoute(name: "default",template: "{controller=Home}/{action=Index}/{id?}");
這是一個(gè)常規(guī)路由,因?yàn)樗⒘艘粋€(gè)約定的URL路徑:
第一路徑段映射到控制器名稱(chēng)
第二路徑映射到操作名稱(chēng)
第三區(qū)段是可選id,用于映射到模型實(shí)體
使用default路由,URL 路徑 /Blog/Index 將映射到BlogController.Index 操作。該映射是基于控制器和操作名稱(chēng),而不是基于命名空間,源文件位置等。
使用常規(guī)路由的默認(rèn)路由可以快速構(gòu)建應(yīng)用程序,而無(wú)需定義每一個(gè)操作的路由。對(duì)于CRUD 操作風(fēng)格的應(yīng)用程序,整個(gè)控制器的URL具有一致性。
3.多路由
可以在UseMvc 里面通過(guò)添加MapRoute 來(lái)添加多個(gè)路由。這樣可以定義多個(gè)約定,或添加專(zhuān)用于特定操作的常規(guī)路由:
app.UseMvc(routes => { routes.MapRoute("blog", "blog/{*article}", defaults: new { Controller = "Blog", Action = "Index" }); routes.MapRoute( name: "default", template: "{controller=Home}/{action=Index}/{id?}"); });
這里的blog 路由是專(zhuān)用常規(guī)路由,這意味著它不采用常規(guī)路由系統(tǒng),而是專(zhuān)用于一個(gè)特定地的動(dòng)作。這個(gè)路由始終映射到BlogController.Index。
路由集合中的路由是有序的,并且會(huì)按照它們被添加的順序進(jìn)行處理。
1.回退
作為請(qǐng)求處理的一部分,MVC將驗(yàn)證路由值是否可以用來(lái)查找應(yīng)用程序中的控制器和操作。如果路由值不匹配操作,那么該路由被認(rèn)為是不匹配的,將嘗試下一個(gè)路由。這一過(guò)程稱(chēng)為回退,因?yàn)槌R?guī)路由有重疊的情況。
2.行動(dòng)歧義
當(dāng)兩個(gè)一致的操作通過(guò)路由時(shí),MVC必須消除歧義,選擇很好操作,否則會(huì)拋出異常。例如:
public class BlogController : Controller { public ActionResult Edit(int id) { return View(); } [HttpPost] public ActionResult Edit(int id, IFormCollection collection) { try { // TODO: Add update logic here return RedirectToAction(nameof(Index)); } catch { return View(); } } }
URL /Blog/Edit/7 可以匹配這兩個(gè)操作,這是MVC控制器的典型模式,其中Edit(int)用于顯示編輯的表單,Edit(int,IFormCollection)用于 處理已提交的表單。為了達(dá)到這個(gè)目的,MVC需要在HTTP POST時(shí)選擇Edit(int,IFormCollection),在其他HTTP動(dòng)詞時(shí)選擇Edit(int)。
HttpPostAttribute 是IActionConstraint 的一個(gè)實(shí)現(xiàn),它只允許在HTTP動(dòng)詞為POST時(shí)選擇動(dòng)作。IActionConstraint的存在使得Edit(int,IFormCollection)比Edit(int)更好匹配。
如果有多個(gè)路由匹配,并且MVC無(wú)法找到一個(gè)很好路由,則會(huì)拋出AmbiguousActionException異常。
3.路由名稱(chēng)
上面的例子中"blog"和"default"字符串是路由名稱(chēng),路由名稱(chēng)為路由提供了一個(gè)邏輯名稱(chēng),以便命名的路由可用于生成URL。在應(yīng)用程序范圍內(nèi)路由必須名稱(chēng)必須是的。
路由名稱(chēng)對(duì)URL匹配或請(qǐng)求的處理沒(méi)有影響,僅用于URL生成。
4.路由特性
特性路由使用一組特性直接將操作映射到路由模板。下面在Configure中調(diào)用app.UseMvc();
沒(méi)有傳遞路由。
public class HomeController : Controller { [Route("")] [Route("Home")] [Route("Home/Index")] public IActionResult Index() { return View(); } [Route("Home/About")] public IActionResult About() { ViewData["Message"] = "Your application description page."; return View(); } }
HomeController.Index操作將會(huì)對(duì) /,/Home 或者/Home/Index 任一URL訪(fǎng)問(wèn)執(zhí)行。
特性路由需要有更多的輸入來(lái)指定一個(gè)路由,而常規(guī)路由處理路由時(shí)更加簡(jiǎn)潔。然而,特性路由允許精準(zhǔn)控制每個(gè)操作的路由模板。
上面的模板中沒(méi)有定義針對(duì) action,area ,controller的路由參數(shù)。實(shí)際上,這些參數(shù)不允許出現(xiàn)在特性路由中,因?yàn)槁酚赡0逡呀?jīng)關(guān)聯(lián)了一個(gè)操作,解析URL中的操作名是沒(méi)有意義的。
特性路由也可以使用HTTP[Verb]特性,如HTTPPost:
[HttpGet("/Blog")] public ActionResult Index() { return View(); }
由于特性路由適用于特定操作,因此很容易使參數(shù)作為模板定義中必須的一部分。下面的例子,id是URL中必須的一部分:
[HttpGet("Blog/Edit/{id}")] public ActionResult Edit(int id) { return View(); }
常規(guī)的默認(rèn)路由定義id參數(shù)作為可選項(xiàng)({id?}),而特性路由的是必須參數(shù),這種可以精準(zhǔn)指定,比如包/Blog/Get 和 /Blog/Get/{id} 分配到不同的操作。
5.組合路由
為了減少特性路由的重復(fù)部分,控制器上的路由特性會(huì)和各個(gè)操作上的路由特性進(jìn)行結(jié)合。任何定義在控制器上的路由模板都會(huì)作為操作路由模板的前綴。
[Route("blog")] public class BlogController : Controller { [HttpGet] public ActionResult GetAll() { return View(); } [HttpGet("{id}")] public ActionResult GetById(int id) { return View(); } }
/blog 匹配GetAll方法, /blog/1 匹配 GetById方法。
注意,如果操作上路由模板以 / 開(kāi)頭時(shí)不會(huì)結(jié)合控制器上的路由模板。
6.特性路由的順序
常規(guī)路由會(huì)根據(jù)定義順序來(lái)執(zhí)行,與之相比,特性路由會(huì)構(gòu)建一個(gè)樹(shù)形結(jié)構(gòu),同時(shí)匹配所有路由。這種看起來(lái)像路由條目被放置在一個(gè)理想的順序中,最具體的路由會(huì)在一般的路由之前執(zhí)行。比如,路由blog/Edit/4 比 blog/{*article} 更加具體。
特性路由使用所有框架提供的路由特有的Order屬性來(lái)配置順序,并根據(jù)Order屬性升序處理路由。默認(rèn)是0,設(shè)置為-1時(shí)會(huì)在沒(méi)有設(shè)置的路由之前執(zhí)行。
7.路由模板中的標(biāo)記替換( [controller] , [action] , [area])
為了方便,特性路由支持標(biāo)記替換,即通過(guò)在在方括號(hào)中封閉一個(gè)標(biāo)記([, ])來(lái)替換對(duì)應(yīng)的名稱(chēng)。標(biāo)記[action],[area],[controller]會(huì)被替換成操作所對(duì)應(yīng)的操作名,區(qū)域名,控制器名。
[Route("[controller]/[action]")] public class BlogController : Controller { [HttpGet]//匹配Blog/GetAll public ActionResult GetAll() { return View(); } }
標(biāo)記替換發(fā)生在構(gòu)建特性路由的最后一步。與上面結(jié)果相同的寫(xiě)法:
public class BlogController : Controller { [HttpGet("[controller]/[action]")]//匹配Blog/GetAll public ActionResult GetAll() { return View(); } }
特性路由也可以與繼承相結(jié)合,即繼承父類(lèi)的路由標(biāo)記。
特性路由支持單個(gè)操作定義路由。如果用IActionConstarint實(shí)現(xiàn)的多個(gè)路由特性定義在一個(gè)操作上時(shí),每個(gè)操作約束與特性定義的路由相結(jié)合:
[Route("Store")] [Route("[controller]")] public class BlogController : Controller { [HttpGet("GetAll")]//匹配 Get Blog/GetAll和 Store/GetAll [HttpPost("Set")]//匹配 Post Blog/Set和 Store/Set public ActionResult GetAll() { return View(); } }
雖然使用多個(gè)路由到一個(gè)操作看起來(lái)很強(qiáng)大,但好還是保持URL的空間簡(jiǎn)單和定義明確。使用多個(gè)路由到操作上僅僅在特殊需要的時(shí)候,比如支持多個(gè)客戶(hù)端。
8.使用IRouteTemplateProvider自定義路由特性
所有框架提供的路由特性([Route(...) ] ,[HttpGet(...)]等)都實(shí)現(xiàn)了 IRouteTemplateProvider 接口。當(dāng)程序啟動(dòng)時(shí),MVC查找控制器類(lèi)和操作方法上都實(shí)現(xiàn) IRouteTemplateProvider 接口的特性來(lái)構(gòu)建儲(chǔ)時(shí)路由集合。
可以通過(guò)實(shí)現(xiàn) IRouteTemplateProvider 來(lái)定義自己的路由特性。每個(gè) IRouteTemplateProvider 都允許定義使用自定義路由模板,順序以及名稱(chēng)的單一路由:
public class MyApiControllerAttribute:Attribute, IRouteTemplateProvider { public string Template => "api/[controller]"; public int? Order { get; set; } public string Name { get; set; } }
當(dāng) [MyApiController] 特性被應(yīng)用時(shí),會(huì)自動(dòng)設(shè)置Template 為 api/[controller] 。
9.使用應(yīng)用程序模型來(lái)自定義特性路由
應(yīng)用程序模型時(shí)啟動(dòng)時(shí)創(chuàng)建的對(duì)象模型,其中包含MVC用于路由和執(zhí)行操作的所有元數(shù)據(jù)。應(yīng)用程序模型包括從路由特性收集的所有數(shù)據(jù)(通過(guò) IRouteTemplateProvider)。我們可以編寫(xiě)約定以在啟動(dòng)時(shí)修改應(yīng)用程序模型為自定義路由行為。
public class NamespaceRoutingConvention:IControllerModelConvention { private readonly string _baseNamespace; public NamespaceRoutingConvention(string baseNamespace) { _baseNamespace = baseNamespace; } public void Apply(ControllerModel controller) { var hasRouteAttributes = controller.Selectors.Any(selector => selector.AttributeRouteModel != null); if (hasRouteAttributes) { //此控制器自定義了一些路由,因此將其視為覆蓋 return; } // 使用命名空間和控制器來(lái)推斷控制器的路由 // // Example: // // controller.ControllerTypeInfo -> "My.Application.Admin.UsersController" // baseNamespace -> "My.Application" // // template => "Admin/[controller]" // // 這使得你的路由大致與你的項(xiàng)目結(jié)構(gòu)一致 // var namespc = controller.ControllerType.Namespace; var template = new StringBuilder(); template.Append(namespc,_baseNamespace.Length+1,namespc.Length- _baseNamespace.Length-1); template.Replace('.','/'); template.Append("/[controller]"); foreach (var selector in controller.Selectors) { selector.AttributeRouteModel = new AttributeRouteModel() { Template = template.ToString() }; } } }
這部分怎么使用,個(gè)人還是不是很清楚,這里只是記錄了官方文檔,有哪位知道可以告訴以下小弟。
10.URL生成
MVC應(yīng)用程序可以使用路由URL的生成特性來(lái)生成URL鏈接到操作。生成URL可以消除硬編碼URL,使代碼更加健壯和易維護(hù)。IUrlHelper 接口是MVC與生成URL路由之間基礎(chǔ)設(shè)施的基本塊??梢酝ㄟ^(guò)控制器,視圖以及視圖組件中的URL屬性找到一個(gè)可用的IUrlHelper實(shí)例:
public class HomeController : Controller { public IActionResult Index() { //生成/Home/Contact var url = Url.Action("Contact"); return View(); } public IActionResult Contact() { ViewData["Message"] = "Your application description page."; return View(); } }
這個(gè)URL路徑是由路由值與當(dāng)前請(qǐng)求相結(jié)合而成的路由創(chuàng)建,并將值傳遞給Url.Action,替換路由模板中對(duì)應(yīng)的值。
上面Url.Action(的例子是常規(guī)路由,但是URL的生成工作與特性路由類(lèi)似,盡管概念不同。在常規(guī)路由中,路由值被用來(lái)擴(kuò)展模板,并且關(guān)于controller和action的路由值通常出現(xiàn)在那個(gè)模板,因?yàn)槁酚善ヅ涞腢RL堅(jiān)持了一個(gè)約定。在特性路由中,關(guān)于controller和action的路由值不允許出現(xiàn)在模板中--它們用來(lái)查找應(yīng)該使用哪個(gè)模板,例如:
//修改Configure public void Configure(IApplicationBuilder app, IHostingEnvironment env) { app.UseMvc(); } public class HomeController : Controller { [HttpGet("/")] public IActionResult Index() { //生成/Home/To/About var url = Url.Action("About"); return View(); } [HttpGet("Home/To/About")] public IActionResult About() { ViewData["Message"] = "Your application description page."; return View(); } }
MVC構(gòu)建了一個(gè)所有特性路由操作的查找表,并且會(huì)匹配controller和action值來(lái)選擇路由模板用于生成URL。
11.通過(guò)操作名生成URL
Url.Action(this IUrlHelper helper, string action)
以及所有相關(guān)的重載都是基于指定控制器名稱(chēng)和操作名來(lái)指定要鏈接的內(nèi)容。
當(dāng)使用Url.Action時(shí),controller 和 action 的當(dāng)前路由值是指定的 -- controller 和 action 的值同時(shí)是環(huán)境值和值的一部分。Url.Action 方法總是使用 controller 和 action 的當(dāng)前值,并且生成路由到當(dāng)前操作的URL路徑。
路由嘗試使用環(huán)境值中的值來(lái)填充信息,同時(shí)我們也可以指定路由參數(shù):
public class HomeController : Controller { public IActionResult Index() { //生成/Blog/Edit/1 var url = Url.Action("Edit", "Blog",new { id=1}); //生成/Blog/Edit/1?color=red var url1 = Url.Action("Edit", "Blog", new { id = 1 ,color="red"}); return View(); } }
如果像創(chuàng)建一個(gè)絕對(duì)URL,可以使用一個(gè)接受protocol的重載:Url.Action("Edit", "Blog",new { id=1},protocol:Request.Scheme);
12.通過(guò)路由名生成URL
IUrlHelper也提供了 Url.RouteUrl 的系列方法,最常見(jiàn)的是指定一個(gè)路由名來(lái)使用具體的路由生成URL,通常沒(méi)有指定控制器名或操作名:
public class HomeController : Controller { public IActionResult Index() { //生成customer/to/url var url = Url.RouteUrl("AboutRoute"); return View(); } [HttpGet("customer/to/url",Name = "AboutRoute")] public IActionResult About() { ViewData["Message"] = "Your application description page."; return View(); } }
在HTML 中生成的URLHtmlHelper,提供了 HtmlHelper 方法 Html.BeginForm 和 Html.ActionLink 來(lái)分別生成<form>和<a>元素。這些方法使用Url.Action方法來(lái)生成一個(gè)URL,并且它們接受類(lèi)似的參數(shù)。Url.RouteLink ,它們有類(lèi)似的功能。TagHelper通過(guò)form和<a> TagHelper生成URL。這些都使用了IUrlHelper 作為它們的實(shí)現(xiàn)。在內(nèi)部視圖中,IUrlHelper 通過(guò)Url 屬性生成任何不包含上述的特定URL。
13.在操作結(jié)果中生成URL
在控制器中常見(jiàn)的一個(gè)用法是生成一個(gè)URL作為操作結(jié)果的一部分。Controller和ControllerBase 基類(lèi)為引用其他操作的操作結(jié)果提供了簡(jiǎn)單方法。一個(gè)典型的方法:
public class HomeController : Controller { public IActionResult Index() { //生成customer/to/url var url = Url.RouteUrl("AboutRoute"); return Redirect(url); //或者 //return RedirectToAction("Contact"); } [HttpGet("customer/to/url",Name = "AboutRoute")] public IActionResult About() { ViewData["Message"] = "Your application description page."; return View(); } public IActionResult Contact() { ViewData["Message"] = "Your contact page."; return View(); } }
RedirectToAction方法有多個(gè)重載可以使用。
14.專(zhuān)用常規(guī)路由的特殊情況
有一種特殊的路由被稱(chēng)為專(zhuān)用常規(guī)路由,下面被命名為blog的路由就是:
app.UseMvc(routes => { routes.MapRoute("blog", "blog/{*article}", defaults: new { Controller = "Blog", Action = "Index" }); routes.MapRoute( name: "default", template: "{controller=Home}/{action=Index}/{id?}"); });
Url.Action("Index", "Home")
會(huì)使用默認(rèn)路由生成URL。
專(zhuān)用常規(guī)路由是依靠默認(rèn)路由的一個(gè)特殊行為,沒(méi)有相應(yīng)的路由參數(shù),以防止路由生成URL“太貪婪”。當(dāng)路由執(zhí)行URL生成時(shí),提供的值必須與默認(rèn)值匹配:否則使用blog的URL生成失敗,因?yàn)橹?code>{controller=Home,action=Index}不匹配{controller=Blog,action=Index}
。然后路由回退嘗試default,并成功。
15.區(qū)域
Areas 是一種MVC功能,用來(lái)將相關(guān)功能組織為一個(gè)組,作為單獨(dú)的路由命名空間(用于控制器操作)和文件夾結(jié)構(gòu)(用于視圖)。使用區(qū)域允許應(yīng)用程序擁有多個(gè)相同名稱(chēng)的控制器——只要它們具有不同的區(qū)域。使用區(qū)域通過(guò)向控制器和操作添加另一個(gè)路由參數(shù),區(qū)域可創(chuàng)建用于路由目的的層次結(jié)構(gòu)。
使用默認(rèn)常規(guī)路由配置MVC,命名一個(gè)OMS區(qū)域的路由:
app.UseMvc(routes => { routes.MapAreaRoute("oms", "OMS", "OManage/{controller}/{action}/{id?}", defaults: new { Controller = "Order", Action = "Index" }); routes.MapRoute( name: "default", template: "{controller=Home}/{action=Index}/{id?}"); });
namespace Blog.Areas.OMS.Controllers { [Area("OMS")] public class OrderController : Controller { // GET: Order public ActionResult Index() { return View(); } }
當(dāng)URL為 /OManage/Order/Edit 時(shí),會(huì)匹配路由值 {area = OMS,controller = Order , action = Edit}
。area路由值是通過(guò)area默認(rèn)值產(chǎn)生的。使用MapRoute方法也可以實(shí)現(xiàn):
routes.MapRoute("oms", "OManage/{controller}/{action}/{id?}", defaults:new {area="OMS" },constraints:new { area = "OMS" });
MapAreaRoute創(chuàng)建一個(gè)路由,同時(shí)使用默認(rèn)路由和area 約束,約束使用提供的區(qū)域名 OMS。默認(rèn)值保證路由總是處理 {area = OMS},約束要求值{area = OMS} 來(lái)進(jìn)行URL生成。
常規(guī)路由是順序依賴(lài)。一般區(qū)域路由放置在前面,因?yàn)閰^(qū)域路由更具體。
AreaAttribute表示控制器屬于一個(gè)區(qū)域的一部分,即這個(gè)控制器是在 OMS 區(qū)域。控制器不帶[Area] 特性則不屬于任何區(qū)域。
當(dāng)在區(qū)域內(nèi)執(zhí)行操作時(shí),區(qū)域的路由值將作為環(huán)境值以用于URL生成,這意味著,在默認(rèn)情況下,區(qū)域?qū)RL生成具有黏性:
namespace Blog.Areas.OMS.Controllers { [Area("OMS")] public class OrderController : Controller { // GET: Order public ActionResult Index() { //生成/OManage/Home/Create var url = Url.Action("Create","Home"); //生成/Home/Create var url1 = Url.Action("Create", "Home",new { area=""}); return View(); } } }
16.IActionConstraint
通常應(yīng)用程序不需要自定義 IActionConstraint,[HttpGet] 特性以及類(lèi)似的特性實(shí)現(xiàn) IActionConstraint 接口,以限制方法的執(zhí)行。
當(dāng)兩個(gè)操作一模一樣,其中一個(gè)操作使用 IActionConstraint,總是認(rèn)為比沒(méi)有使用的操作更好,因?yàn)樗灰暈楦泳唧w,并且兩個(gè)操作都可以在匹配是被選中。(沒(méi)有使用的操作會(huì)匹配任何HTTP謂詞)
概念上,IActionConstraint 是重載的一種形式,但不是使用相同名稱(chēng)的重載,它是匹配相同URL操作的重載。特性路由也使用 IActionConstraint ,并且可以導(dǎo)致不同控制器的操作都被視為候選操作。
實(shí)現(xiàn) IActionConstraint 最簡(jiǎn)單的方式是創(chuàng)建一個(gè)類(lèi)派生自 System.Attribute ,并且將它放置到操作和控制器上。MVC會(huì)自動(dòng)發(fā)現(xiàn)任何作為特性被應(yīng)用的 IActionConstraint。你可以使用程序模型來(lái)應(yīng)用約束,可能是最靈活的方法,因?yàn)樗试S對(duì)它們?nèi)绾伪粦?yīng)用進(jìn)行元編程。
一個(gè)例子,一個(gè)約束選擇一個(gè)基于來(lái)自路由數(shù)據(jù)的 country code 操作:
public class CountrySpecificAttribute:Attribute,IActionConstraint { private readonly string _countryCode; public CountrySpecificAttribute(string countryCode) { _countryCode = countryCode; } public int Order { get { return 0; } } public bool Accept(ActionConstraintContext context) { return string.Equals( context.RouteContext.RouteData.Values["country"].ToString(), _countryCode,StringComparison.OrdinalIgnoreCase); } }
Accept 方法返回true,表示當(dāng)country路由值匹配時(shí)操作時(shí)匹配的。這個(gè)和 RouteValueAttribute 不同,因?yàn)樗试S回退到一個(gè)非特性操作。這個(gè)例子展示了如果定義一個(gè) en-US 操作,然后國(guó)家代碼是 fr-FR,則會(huì)回退到一個(gè)更通用的控制器,這個(gè)控制器沒(méi)有應(yīng)用 [CountrySpecific(...)] 。
Order屬性和 [HttpGet] 特性中的Order屬性一樣,用來(lái)決定運(yùn)行順序。
以上是“ASP.NET Core MVC之路由的示例分析”這篇文章的所有內(nèi)容,感謝各位的閱讀!相信大家都有了一定的了解,希望分享的內(nèi)容對(duì)大家有所幫助,如果還想學(xué)習(xí)更多知識(shí),歡迎關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道!
分享名稱(chēng):ASP.NETCoreMVC之路由的示例分析-創(chuàng)新互聯(lián)
分享URL:http://muchs.cn/article44/dooeee.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供搜索引擎優(yōu)化、網(wǎng)站建設(shè)、建站公司、全網(wǎng)營(yíng)銷(xiāo)推廣、外貿(mào)網(wǎng)站建設(shè)、微信公眾號(hào)
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶(hù)投稿、用戶(hù)轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀(guān)點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話(huà):028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來(lái)源: 創(chuàng)新互聯(lián)
猜你還喜歡下面的內(nèi)容