Asp.net核心2.1路由问题
Asp.net Core 2.1 Routing Issue
我在 asp.net 核心 2.1 中尝试了一些路由,但遇到路由问题...
Startup.cs -> 配置方法
app.UseMvc(routes => {
routes.MapRoute(
name: "default",
template: "{Controller=Demo}/{Action=Index}/{id?}");
});
DemoController.cs
[Route("demo")]
public class DemoController : Controller
{
[Route("")]
[Route("index")]
[Route("MyDemoPage")]
[Route("~/")]
public IActionResult Index()
{
return View();
}
[Route("demo2/{id}")]
[Route("cj/{id}")]
public IActionResult Demo2(int id)
{
ViewBag.id = id;
return View("Demo2");
}
[Route("demo3/{id1}/{id2}")]
[Route("cc/{id1}/{id2}")]
public IActionResult Demo3(int id1,string id2)
{
ViewBag.id = id1;
ViewBag.id2 = id2;
return View("Demo3");
}
}
Index.cshtml 页
@*[Route("demo2/{id}")]*@
<br />
<a asp-controller="demo" asp-action="demo2" asp-route-id="123">Demo2</a>
@*Above Tag renders :> <a href="/demo/cj/123">Demo2</a>*@ Link 1
<br />
@*[Route("cj/{id}")]*@
<br />
<a asp-controller="demo" asp-action="cj" asp-route-id="07">Demo2 via route CJ</a>
@*Above Tag renders :> <a href="/demo/cj/07">Demo2 via route CJ</a>*@ Link 2
<br />
@*[Route("demo3/{id1}/{id2}")]*@
<br />
<a asp-controller="demo" asp-action="demo3" asp-route-id1="123" asp-route-id2="P001">Demo3</a>
@*Above Tag renders :> <a href="/demo/cc/123/P001">Demo3</a>*@ Link 3
<br />
@*[Route("cc/{id1}/{id2}")]*@
<br />
<a asp-controller="demo" asp-action="cc" asp-route-id1="123" asp-route-id2="abc">Demo via CC</a>
@*Above Tag renders :> <a href="/demo/cc?id1=123&id2=abc">Demo via CC</a>*@ Link 4
Demo2.cshtml
@*[Route("index")]*@
<br />
<a asp-controller="demo" asp-action="index">Index Page</a>
@*Above Tag renders :> <a href="/demo/MyDemoPage">Index Page</a>*@ Link 5
<br />
@*[Route("MyDemoPage")]*@
<br />
<a asp-controller="demo" asp-action="MyDemoPage">Index Page via MyDemoPage
Route</a>
@*Above Tag renders :> <a href="/demo/MyDemoPage">Index Page via MyDemoPage
Route</a>*@ Link 6
我很困惑为什么 Link 4 和 Link 3 在 index.cshtml 和
Link 5 & Link 6 呈现相同的 href
请帮忙...
由于Link 5 & Link 6的不同结果,它们是由不同的规则生成的。
对于URL生成,RouteCollection
调用GetVirtualPath使用IRouter
生成url。有两个默认的 irouter,Microsoft.AspNetCore.Mvc.Internal.AttributeRoute
和 Microsoft.AspNetCore.Mvc.Internal.MvcRouteHandler
。
对于asp-action="index"
,由AttributeRoute
和GetMatches will order the MyDemoPage
before index
. You could check OutboundMatchResultComparer 处理,检查比较逻辑。如果把[Route("MyDemoPage")]
改成[Route("myDemoPage")]
,就会生成/demo/index。
asp-action="MyDemoPage"
,GetMatches
return IList<OutboundMatchResult>
的零计数。然后,它转到 MvcRouteHandler
,并调用 RouteBase
。 _binder.BindValues(values.AcceptedValues); 将生成 /demo/MyDemoPage。
GetMatches
的不同结果由控制器操作中是否存在 asp-action
的值控制。对于你的场景,Index
存在,但MyDemoPage
不存在,MyDemoPage
没有对应的方法。
更新
再来一次,key不同的结果是由是否
action
是真正存在于Controller方法中。
对于asp-action="cc"
,DemoController
中没有cc
动作,与Controller MVC Binder
对应,格式为/demo/cc?id1=123&id2=abc
。
对于asp-action="demo3"
,有一个动作叫做demo3
,它是由Router Attribute Binder
生成的,会依次生成_template = "demo/cc/{id1}/{id2}"
和_template = "demo/demo3/{id1}/{id2}"
。对于订单,它将 return /demo/cc/123/P001
.
我在 asp.net 核心 2.1 中尝试了一些路由,但遇到路由问题...
Startup.cs -> 配置方法
app.UseMvc(routes => {
routes.MapRoute(
name: "default",
template: "{Controller=Demo}/{Action=Index}/{id?}");
});
DemoController.cs
[Route("demo")]
public class DemoController : Controller
{
[Route("")]
[Route("index")]
[Route("MyDemoPage")]
[Route("~/")]
public IActionResult Index()
{
return View();
}
[Route("demo2/{id}")]
[Route("cj/{id}")]
public IActionResult Demo2(int id)
{
ViewBag.id = id;
return View("Demo2");
}
[Route("demo3/{id1}/{id2}")]
[Route("cc/{id1}/{id2}")]
public IActionResult Demo3(int id1,string id2)
{
ViewBag.id = id1;
ViewBag.id2 = id2;
return View("Demo3");
}
}
Index.cshtml 页
@*[Route("demo2/{id}")]*@
<br />
<a asp-controller="demo" asp-action="demo2" asp-route-id="123">Demo2</a>
@*Above Tag renders :> <a href="/demo/cj/123">Demo2</a>*@ Link 1
<br />
@*[Route("cj/{id}")]*@
<br />
<a asp-controller="demo" asp-action="cj" asp-route-id="07">Demo2 via route CJ</a>
@*Above Tag renders :> <a href="/demo/cj/07">Demo2 via route CJ</a>*@ Link 2
<br />
@*[Route("demo3/{id1}/{id2}")]*@
<br />
<a asp-controller="demo" asp-action="demo3" asp-route-id1="123" asp-route-id2="P001">Demo3</a>
@*Above Tag renders :> <a href="/demo/cc/123/P001">Demo3</a>*@ Link 3
<br />
@*[Route("cc/{id1}/{id2}")]*@
<br />
<a asp-controller="demo" asp-action="cc" asp-route-id1="123" asp-route-id2="abc">Demo via CC</a>
@*Above Tag renders :> <a href="/demo/cc?id1=123&id2=abc">Demo via CC</a>*@ Link 4
Demo2.cshtml
@*[Route("index")]*@
<br />
<a asp-controller="demo" asp-action="index">Index Page</a>
@*Above Tag renders :> <a href="/demo/MyDemoPage">Index Page</a>*@ Link 5
<br />
@*[Route("MyDemoPage")]*@
<br />
<a asp-controller="demo" asp-action="MyDemoPage">Index Page via MyDemoPage
Route</a>
@*Above Tag renders :> <a href="/demo/MyDemoPage">Index Page via MyDemoPage
Route</a>*@ Link 6
我很困惑为什么 Link 4 和 Link 3 在 index.cshtml 和 Link 5 & Link 6 呈现相同的 href 请帮忙...
由于Link 5 & Link 6的不同结果,它们是由不同的规则生成的。
对于URL生成,RouteCollection
调用GetVirtualPath使用IRouter
生成url。有两个默认的 irouter,Microsoft.AspNetCore.Mvc.Internal.AttributeRoute
和 Microsoft.AspNetCore.Mvc.Internal.MvcRouteHandler
。
对于asp-action="index"
,由AttributeRoute
和GetMatches will order the MyDemoPage
before index
. You could check OutboundMatchResultComparer 处理,检查比较逻辑。如果把[Route("MyDemoPage")]
改成[Route("myDemoPage")]
,就会生成/demo/index。
asp-action="MyDemoPage"
,GetMatches
return IList<OutboundMatchResult>
的零计数。然后,它转到 MvcRouteHandler
,并调用 RouteBase
。 _binder.BindValues(values.AcceptedValues); 将生成 /demo/MyDemoPage。
GetMatches
的不同结果由控制器操作中是否存在 asp-action
的值控制。对于你的场景,Index
存在,但MyDemoPage
不存在,MyDemoPage
没有对应的方法。
更新
再来一次,key不同的结果是由是否
action
是真正存在于Controller方法中。
对于asp-action="cc"
,DemoController
中没有cc
动作,与Controller MVC Binder
对应,格式为/demo/cc?id1=123&id2=abc
。
对于asp-action="demo3"
,有一个动作叫做demo3
,它是由Router Attribute Binder
生成的,会依次生成_template = "demo/cc/{id1}/{id2}"
和_template = "demo/demo3/{id1}/{id2}"
。对于订单,它将 return /demo/cc/123/P001
.