3

I have an action with the same name, one expecting no parameters and the other expecting an ID, when i try navigate through my url i get the following exception.

An unhandled exception occurred while processing the request.

AmbiguousActionException: Multiple actions matched. The following actions matched route data and had all constraints satisfied:

Mailer.Controllers.MailBuilderController.MailBody (Mailer) Mailer.Controllers.MailBuilderController.MailBody (Mailer)

My MailBuilder controller.

//[HttpGet("mailbuilder/MailBody")]
public IActionResult MailBody()
{
   Body model = new Body();
   return View(model);
}

//[HttpGet("mailbuilder/MailBody/{id}")]
public IActionResult MailBody(int id)
{
   Body model = _mailBuilderService.GetBody(id);
   return View(model);
}

If i remove the comments above i am able to navigate but i am not able to redirect to action in the below method.

public IActionResult SaveBody(Body model)
{
  _mailBuilderService.AddBody(model);
  return RedirectToAction("MailBody", model.Id);
}

2 Answers 2

2

If it is anything like the previous versions of MVC then you will need to uncomment those route attributes ([HttpGet("mailbuilder/MailBody/{id}")]) but also rename your post action to the same name. Alternatively, you can set the action in the form helper (if that still exists).

Also so the router can find the right method you need to provide the route data as an object return RedirectToAction("MailBody", new { id = model.Id });

The following code example is untested but I think it will be on the right track...

[HttpGet("mailbuilder/MailBody")]
public IActionResult MailBody()
{
   Body model = new Body();
   return View(model);
}

[HttpGet("mailbuilder/MailBody/{id}")]
public IActionResult MailBody(int id)
{
   Body model = _mailBuilderService.GetBody(id);
   return View(model);
}

[HttpPost("mailbuilder/MailBody")]
public IActionResult MailBody(Body model)
{
  _mailBuilderService.AddBody(model);
  return RedirectToAction("MailBody", new { id = model.Id });
}
Sign up to request clarification or add additional context in comments.

2 Comments

On second thought - your actual issue is probably the second issue I described with the routedata not being an object...
Yes, the problem is that his RedirectToAction is using "Id" with a capital I, which will not match the actual lowercase id when generating the url. You need new { id = model.Id } for the route builder to create the correct route. Whether or not his post action is the same name is irrelevant.
1

What about making the int nullable?

public IActionResult MailBody(int? id)
{
   Body model = id.HasValue ? _mailBuilderService.GetBody(id.Value) : new Body();
   return View(model);
}

To clarify, if you're using default routing then the id is likely set to id = RouteParameter.Optional so in essence the two ActionResults are the same.

4 Comments

@Dillon I like the the idea of the null-able int and only having one action. However i get a can't convert int? to int when trying to call get body. Is there a better way to handle this then _mailBuilderService.GetBody(int.Parse(id.ToString()))
@Pomster try id.Value?
@Dillon - I've removed the downvote, since you removed the inaccurate information. Yes, his post has the routes commented out, but he says when he uncomments them he has the routing issue. So the "ambiguous" issue is because he doesn't have routing, and the routing issue is because he's creating the wrong route data item.
@ErikFunkenbusch You are correct, because with them commented out he is likely defaulting to the template defaults in the RouteConfig.cs. I was simply supplying a solution to the big yellow ambiguous error in the OP, whereas as Michael pointed out the actual issue was with the RouteParameters in the Redirect. Cheers.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.