I tried some routing in asp.net core 2.1 and facing a issue with routing...
Startup.cs -> Configure Method
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 Page
@*[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
I am confuse why did Link 4 & Link 3 are different in index.cshtml and Link 5 & Link 6 rendered same href Please help...
For the reason that different result for Link 5 & Link 6, they are generated by different rules.
For URL generation, RouteCollection
call GetVirtualPath to use IRouter
to generate the url. There are two default irouter, Microsoft.AspNetCore.Mvc.Internal.AttributeRoute
and Microsoft.AspNetCore.Mvc.Internal.MvcRouteHandler
.
For asp-action="index"
, it is handled by AttributeRoute
and GetMatches will order the MyDemoPage
before index
. You could check OutboundMatchResultComparer to check compare logic. If you change [Route("MyDemoPage")]
to [Route("myDemoPage")]
, it will generate /demo/index.
For asp-action="MyDemoPage"
, GetMatches
return zero count for IList<OutboundMatchResult>
. Then, it goes to MvcRouteHandler
, and call RouteBase
. _binder.BindValues(values.AcceptedValues); will generate /demo/MyDemoPage.
The different result for GetMatches
is controlled by whether value for asp-action
exist in the Controller Action. For your scenario, Index
is exist, but MyDemoPage
not, there is no corresponding method for MyDemoPage
.
Update
One more time, the key different result is caused by whether the
action
is real exist in the Controller method.
For asp-action="cc"
, there is no cc
action in DemoController
, it goes with Controller MVC Binder
, and format as /demo/cc?id1=123&id2=abc
.
For asp-action="demo3"
, there is action called demo3
, it is generated by Router Attribute Binder
, and will generate _template = "demo/cc/{id1}/{id2}"
and _template = "demo/demo3/{id1}/{id2}"
in order. For the order, it will return /demo/cc/123/P001
.