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

时间:2013-07-03 20:38:52

标签: c# asp.net-mvc rest asp.net-mvc-4 routes

我有两个动作,我希望我的路线/users/users/{id}不同。但它会让我错误。

是否有可能实现这种排序而无需手动创建每条路由,我将拥有其他控制器,这些控制器将遵循类似的模式,并且为所有这些模式编写自定义路由似乎是多余的,而且总的来说是个坏主意。 / p>

错误

  

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

代码

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

    public ActionResult Index(int id)
    {
        return null;
    }
}

5 个答案:

答案 0 :(得分:4)

您需要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;
    }
}

我不确定上述内容是否有效,但应该给你一个想法。

答案 1 :(得分:3)

你也可以尝试这样的事情:

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

答案 2 :(得分:1)

Max Toro的答案很有用,虽然我需要指定更多参数。

我将selector属性更改为:

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)
{
    //....
}

答案 3 :(得分:0)

将[HttpGet]作为第一种方法!

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

    public ActionResult Index(int id)
    {
        return null;
    }
}

答案 4 :(得分:-1)

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

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

/{action}/{id}

并且需要actionid可选...允许基于URL映射操作。也可以指定{controller}