C# 如何使用不同的参数为同一控制器方法设置不同的路由?
我的ReportController如下所示:C# 如何使用不同的参数为同一控制器方法设置不同的路由?,c#,asp.net,asp.net-core,routing,C#,Asp.net,Asp.net Core,Routing,我的ReportController如下所示: public IActionResult ReportDetails(int? reportId){ .... } 及 我试着做一些路由,但失败了。在Startup.cs中编写的实际代码: app.UseMvc(routes => { routes.MapRoute( name: "ReportDetailsValidation",
public IActionResult ReportDetails(int? reportId){
....
}
及
我试着做一些路由,但失败了。在Startup.cs中编写的实际代码:
app.UseMvc(routes =>
{
routes.MapRoute(
name: "ReportDetailsValidation",
template: "descriptionValidation",
defaults: new { controller = "Report", action = "ReportDetails", reportId ="{reportId}", approved = "{approved}" }
);
routes.MapRoute(
name: "ReportDetails",
template: "description",
defaults: new { controller = "Report", action = "ReportDetails"}
);
routes.MapRoute(
name: "default",
template: "{controller=Home}/{action=Index}/{id?}");
});
如我所见,我需要匹配以下URL:/Report/ReportDetails?reportId=7用于第一个和
/Report/ReportDetails?reportId=7&approved=True第二次您可以按照此了解路由
[HttpGet("Report/ReportDetails/{reportId}")]
[HttpGet("Report/ReportDetails/{reportId}/{approved}")]
public IActionResult ReportDetails(int? reportId, bool? approved) {
....
}
您可以创建
操作方法SelectorAttribute
。在控制器中,您可以将属性添加到这两个方法中,以使正确的方法与URL匹配
例如,您可以创建一个参数existsattribute
,确定该方法是否合适,然后使用
[ParameterExists('approved', false)]
public IActionResult ReportDetails(int? reportId){
....
}
[ParameterExists('approved', true)]
public IActionResult ReportDetails(int? reportId, bool ? approved) {
....
}
如何实现这样一个属性仍然是读者的难题。(没那么难。)
例如,这里有一个基于参数值选择API调用的属性
public class FormPostFilterAttribute : ActionMethodSelectorAttribute
{
private readonly string _elementId;
private readonly string _requiredValue;
public FormPostFilterAttribute(string elementId, string requiredValue)
{
_elementId = elementId;
_requiredValue = requiredValue;
}
public override bool IsValidForRequest(ControllerContext controllerContext, System.Reflection.MethodInfo methodInfo)
{
if (string.IsNullOrEmpty(controllerContext.HttpContext.Request.Form[_elementId]))
{
return false;
}
return (controllerContext.HttpContext.Request.Form[_elementId] == _requiredValue);
}
}
您不能这样做,比如有两个名称相同、参数不同的方法,因为您应该得到模糊usactionexception ASP核心操作选择器在选择操作期间不关心操作的参数。因此,一个管线模板不能有两个操作。唯一的解决方法是使用动作约束(如HttpGet和HttpPost)。 你可以。(请参见选择最佳候选方法) 从理论上讲,如果参数很重要,那么基于参数选择操作的逻辑应该在SelectBestActions方法中,但它忽略了参数 在您的情况下,好的选择似乎只有一种方法:
public IActionResult ReportDetails(int? reportId, bool? approved) {
....
}
然后检查approved是否为NULL(/Report/ReportDetails?reportId=7),然后执行第1个逻辑,否则(/Report/ReportDetails?reportId=7&approved=True)执行第2个逻辑。若逻辑包含许多行,那个么可以在新方法中提取它们并调用它
public IActionResult ReportDetails(int? reportId, bool? approved) {
if (approved != null)
{
//implement logic for 2nd case(approved=True)
}
//implement logic for 1st case (just reportId=7)
}
你可以使用RouteAttribute
[Route("ReportDetails/{reportId}")]
public IActionResult ReportDetails(int? reportId){
....
[Route("ReportDetails/{reportId}/{approved}")]
public IActionResult ReportDetails(int? reportId, bool ? approved) {
....
你的网址将是
/报告/ReportDetails/7第一次和第二次
/Report/ReportDetails/7/第二个为True
这将与默认的startup.cs一起使用
app.UseMvc(routes =>
{
routes.MapRoute(
name: "default",
template: "{controller=Home}/{action=Index}/{id?}");
});
是的,我考虑过这一点,但正如我提到的,我的链接是我指定的。我在views@Html.ActionLinkFor中使用了它(我不明白为什么它在视图名称后不加“/”)。我本来希望链接与您的链接相同,在标准情况下,您将得到提到的异常,但使用相同名称的多个方法完全没有问题。您只需使用
ActionMethodSelectorAttribute
s来帮助选择过程(请参见我的答案)。但是在这里介绍的特定情况下,您是对的,不需要这样做,而且使用默认参数更容易。
app.UseMvc(routes =>
{
routes.MapRoute(
name: "default",
template: "{controller=Home}/{action=Index}/{id?}");
});