6

/users我有两个动作,我希望我的路线/users/{id}与众不同。但是它给我带来了错误。

是否有可能在不手动创建每条路由的情况下实现这种事情,我将拥有其他遵循类似模式的控制器,并且为所有这些控制器编写自定义路由通常看起来是多余的和坏主意。

错误

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

代码

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

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

5 回答 5

5

你需要一个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;
    }
}

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

于 2013-07-04T02:28:11.103 回答
3

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

public class UsersController : Controller
{   
    public ActionResult Index(int? id)
    {
        if(id == null) {
            // case A
        }
        else {
            // case B
        }
    }
}
于 2016-01-10T10:44:53.233 回答
2

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)
{
    //....
}
于 2017-08-10T16:33:33.457 回答
0

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

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

    public ActionResult Index(int id)
    {
        return null;
    }
}
于 2014-08-04T15:54:13.417 回答
-1

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

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

/{action}/{id}

并使其成为action必需但id可选......这将允许基于 URL 映射操作。也可以指定{controller}

于 2013-07-03T20:41:13.523 回答