Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/325.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何使用不同的参数为同一控制器方法设置不同的路由?_C#_Asp.net_Asp.net Core_Routing - Fatal编程技术网

C# 如何使用不同的参数为同一控制器方法设置不同的路由?

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",

我的ReportController如下所示:

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?}");
        });