对控制器类型{1}的操作{0}的当前请求不明确

本文关键字:请求 不明确 操作 控制器 类型 | 更新日期: 2023-09-27 18:20:58

我有两个操作,我希望我的路由/users/users/{id}不同。然而,这让我犯了一个错误。

有没有可能在不手动创建每个路由的情况下实现这种排序,我会有其他控制器遵循类似的模式,为所有这些控制器编写自定义路由似乎是多余的,总体来说是个坏主意。

错误

对控制器类型的操作"Index"的当前请求"UsersController"在以下操作方法之间不明确:类型上的System.Web.Mvc.ActionResult Index()Api.Controllers.UsersController System.Web.Mvc.ActionResultApi.Controllers.UsersController 类型的索引(Int32)

代码

public class UsersController : Controller
{
    public ActionResult Index()
    {
        return null;
    }
    public ActionResult Index(int id)
    {
        return null;
    }
}

对控制器类型{1}的操作{0}的当前请求不明确

您需要一个ActionMethodSelector:

public class RequiresParameterAttribute : ActionMethodSelectorAttribute {
   readonly string parameterName;
   public RequiresParameterAttribute(string parameterName) {
      this.parameterName = parameterName;
   }
   public override bool IsValidForRequest(ControllerContext controllerContext, MethodInfo methodInfo) {
      return controllerContext.RouteData.Values[parameterName] != null;
   }
}

控制器:

public class UsersController : Controller
{
    public ActionResult Index()
    {
        return null;
    }
    [RequiresParameter("id")]
    public ActionResult Index(int id)
    {
        return null;
    }
}

我不确定以上是否可行,但应该会给你一个想法。

您也可以尝试以下操作:

public class UsersController : Controller
{   
    public ActionResult Index(int? id)
    {
        if(id == null) {
            // case A
        }
        else {
            // case B
        }
    }
}

Max Toro的回答很有用,尽管我需要指定更多的参数。

我将选择器属性更改为:

public class RequiresParameterAttribute : ActionMethodSelectorAttribute
{
    readonly string[] parameterName;
    public RequiresParameterAttribute(string[] parameterName)
    {
        this.parameterName = parameterName;
    }
    public override bool IsValidForRequest(ControllerContext controllerContext, MethodInfo methodInfo)
    {
        //somehow, in my version of MVC controllerContext.RouteData.Values was not returning querystring parameters at all...
        var queryString = controllerContext.RequestContext.HttpContext.Request.QueryString; 
        foreach (string param in parameterName)
        {
            if (queryString.GetValues(param) == null)
                return false;
        }
        return true;
    }
}

然后它可以这样使用:

[RequiresParameter(new string[] { "id", "id2", "id3" })]
public ActionResult Index(int id, int id2, int id3)
{
    //....
}

Put[HttpGet]用于第一个方法!

public class UsersController : Controller
{
    [HttpGet] 
    public ActionResult Index()
    {
        return null;
    }
    public ActionResult Index(int id)
    {
        return null;
    }
}

我只需要删除第一个不带参数的方法,并使整数在路由中是可选的,在控制器中是可为null的int。然后,您可以根据单个操作方法中的整数为null来决定要做什么。

您可以将动作定义为路线的一部分:

/{action}/{id}

并使action是必需的,但id是可选的。。。这将允许基于URL的动作映射。也可以指定{controller}