Current request for action {0} on controller type {1} is ambiguous

I have two actions, and I want my routes /users and /users/{id} be different. However, this causes me an error.

Is it possible to implement this sorting without manually creating each route, I will have other controllers that follow a similar pattern and write custom routes for all of them, it seems redundant and bad in general.

Error

The current request for the Index action for the UsersController controller type is ambiguous between the following methods: System.Web.Mvc.ActionResult Index () as Api.Controllers.UsersController System.Web.Mvc.ActionResult Index (Int32) as Api.Controllers .UsersController

code

 public class UsersController : Controller { public ActionResult Index() { return null; } public ActionResult Index(int id) { return null; } } 
+6
source share
5 answers

You need an 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; } } 

And the controller:

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

I'm not sure what the above will work, but should give you an idea.

+4
source

You can also try something like this:

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

Max Toro's answer was helpful, although I needed to specify additional parameters.

I changed the selector attribute to this:

 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; } } 

And then it can be used as such:

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

Put [HttpGet] for the first method!

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

I would just delete the first method, which takes no parameters and makes an integer both optional in routing and nullable int in the controller. Then you can decide what to do based on the integer null value in one action method.

You can define an action as part of a route:

 /{action}/{id} 

And make the action mandatory, but id optional ... which will allow the display of the action based on the URL. You can also specify {controller} .

-1
source

Source: https://habr.com/ru/post/948654/


All Articles