ASP.NET MVC Ambiguous Action Methods

ASP.NET MVC ambiguous action methods

MVC doesn't support method overloading based solely on signature, so this will fail:

public ActionResult MyMethod(int someInt) { /* ... */ }
public ActionResult MyMethod(string someString) { /* ... */ }

However, it does support method overloading based on attribute:

[RequireRequestValue("someInt")]
public ActionResult MyMethod(int someInt) { /* ... */ }

[RequireRequestValue("someString")]
public ActionResult MyMethod(string someString) { /* ... */ }

public class RequireRequestValueAttribute : ActionMethodSelectorAttribute {
public RequireRequestValueAttribute(string valueName) {
ValueName = valueName;
}
public override bool IsValidForRequest(ControllerContext controllerContext, MethodInfo methodInfo) {
return (controllerContext.HttpContext.Request[ValueName] != null);
}
public string ValueName { get; private set; }
}

In the above example, the attribute simply says "this method matches if the key xxx was present in the request." You can also filter by information contained within the route (controllerContext.RequestContext) if that better suits your purposes.

Ambiguous action methods

You can't have the same HTTP verb for the same action name. In other words, having HttpGet for the same action name, even an overload, isn't possible.

You have three options:

Change one or your action methods to a different HTTP action verb...

[HttpGet]
public ActionResult Index()
{
//..
}

[HttpPost]
public ActionResult Index(string country)
{
//..
}

Or, change the name of your action method...

public ActionResult CountryIndex(string country)
{
ViewBag.Message = "my country=" + country;

return View();
}

Or, you can change the action name from the overloaded method...

public ActionResult Index()
{
//..
}

[ActionName("IndexByCountryName")]
public ActionResult Index(string country)
{
//..
}

Working example

This uses the last option, keeping the method name overloaded but specify the ActionNameAttribute for the overload

Actions

    public ActionResult Index()
{
ViewBag.Message = "no country selected!";

return View();
}

[ActionName("IndexByCountry")]
public ActionResult Index(string country)
{
ViewBag.Message = string.Format("County selected :: {0}", country);

// the below ActionResult reuses the Index view but
// here you could have a separate view for the country
// selection if you like
//
return View("Index");
}

Routes

        routes.MapRoute(
name: "ByCountry",
url: "{country}",
defaults: new { controller = "Home", action = "IndexByCountry" }
);

routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);

MVC5 ambiguous action methods in controller

This isn't possible since you're trying to do a GET request for each method. The ASP.NET MVC action selector doesn't know which method to pick.

If it makes sense and you're able you can use the HttpGet or HttpPost attributes to differentiate the method for each type of HTTP request. It doesn't sound like that makes sense in your case.

Ambiguous Action Methods - ASP.net MVC

It appears his question was more complicated than yours. Rather than the RequiredRouteValues class he created, you should be able to use the RequiredRequestValue attribute he used that Levi created.

You'll have to convert to vb.net yourself, but stick to Levi's answer, and not the route modification.

James

Ambiguous action methods with different HttpMethod

This is because BeginForm uses GetVirtualPath internally to get the url from the route table. The first link is added to the route table in your example.

Simply editing the POST method with the following should do the trick:

[HttpPost]
[ValidateAntiForgeryToken]
[Route("Add")]
public async Task<ActionResult> Add(AddTransactionViewModel model)

Ambiguous action method

You could have one Action that takes both parameter types.

The model binder should then fill them with whatever data is posted and you can figure out which is right in your Action method.

[HttpPost]
public virtual ActionResult Edit( CorporateCustomer c, PrivateCustomer p )
{
...
}

MVC Exception: Ambiguous between the following action methods

So you clicked the SignIn button which is routed to the Login action. The error is caused because HttpParamActionAttribute is returning true for IsValidName for both SignIn and Login actions.

Your HttpParamActionAttribute returns true for IsValidName against the Login action because the Login action matches by name.

Now your other HttpParamActionAttribute on SignIn also returns true because request["SignIn"] is not equal to null.

Change your view to look for an action that is not "LogIn" and also not "SignIn". That way only the action that matches the button name will return true for IsValidName.



Related Topics



Leave a reply



Submit