我试着做一些简单的事情。我想有不同的操作名称和不同的方法名称:
public class SuperController: Controller
{
[HttpGet("dosth")]
public IActionResult DoSomethingWithThoseParameters(int id, string token)
{
}
}
查看控制器上没有Route
属性。
在这种情况下,标签助手asp-action
完美运行。但我认为我的行动dosth
会被放在:localhost/Super/dosth
但事实并非如此。所以我发现我可能应该为整个控制器设置路由,如下所示:
[Route("[controller]")]
public class SuperController: Controller
{
[HttpGet("dosth")]
public IActionResult DoSomethingWithThoseParameters(int id, string token)
{
}
public IActionResult Register()
{
return View();
}
}
但现在asp-action
停止工作了。例如:
<a asp-controller="Super" asp-action="Register">
创建定位点到:localhost/Super
,而不是定位点:localhost/Super/Register
当我从控制器中删除路由标签时,它会再次工作。
我的映射配置为标准 说:
app.UseEndpoints(endpoints =>
{
endpoints.MapControllerRoute(
name: "default",
pattern: "{controller=Home}/{action=Index}/{id?}");
endpoints.MapRazorPages();
});
那么,当整个控制器上有Route
属性时,为什么asp-action
不起作用
在控制器上应用[Route]
属性将启用所有控制器方法的属性路由。因此,通过这样做,您强迫自己为每种方法提供路线(以一种或另一种方式)。
使用[Route("[controller]")]
控制器操作的基本路由模板只是控制器名称,因此,如果您有多个操作,但未应用[Route]
或[HttpGet]
(以及其他 HTTP 谓词)属性:
[Route("[controller]")]
public class SuperController: Controller
{
public IActionResult DoSomethingWithThoseParameters(int id, string token)
{
}
public IActionResult Register()
{
return View();
}
}
。你会得到一个AmbiguousMatchException
因为多个控制器操作将匹配相同的路由:
/超
您可以为每个操作显式指定路由:
[Route("[controller]")]
public class SuperController: Controller
{
[HttpGet("dosth")]
public IActionResult DoSomethingWithThoseParameters(int id, string token)
{
}
[HttpGet("Register")]
public IActionResult Register()
{
return View();
}
}
或者将操作名称指定为控制器级别已有的预期路由的一部分:
[Route("[controller]/[action]")]
public class SuperController : Controller
{
public IActionResult DoSomethingWithThoseParameters(int id, string token)
{
}
public IActionResult Register()
{
return View();
}
}
然后,您不必指定操作的路由,因为您在控制器级别应用了路由模板。您的操作将继承该路由模板。
但是,请注意,为了覆盖它,您必须覆盖所有内容,否则您将附加到路由模板。
[HttpGet("/[controller]/dosth")]
public IActionResult DoSomethingWithThoseParameters(int id, string token)
{
}
在官方文档中阅读有关路由的更多信息。