4

I've been trying out Asp.NET Core, specifically Areas. Right now I'm running into an issue where I get an exception if I add more than one view to my controller.

This is my exception:

An unhandled exception occurred while processing the request.

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

Forum.Areas.Admin.Controllers.AdminController.Index (Forum) Forum.Areas.Admin.Controllers.AdminController.Testing (Forum)

This is how I register the route:

  app.UseMvc(routes =>
  {
    routes.MapRoute("adminRoute", "Admin/{controller}/{action}/{id?}");

    routes.MapRoute(
      name: "default",
      template: "{controller=Home}/{action=Index}/{id?}");
  });

My controller:

namespace Forum.Areas.Admin.Controllers
{
  [Area("Admin")]
  [Route("admin")]
  public class AdminController : Controller
  {

    public IActionResult Index()
    {
      return View();
    }

    public IActionResult Testing()
    {
      return Content("Testing area!");
    }
  }
}

My project structure:

Project structure

Other similar questions seem to have ambiguous actions over different controllers, but in my case it's two different action names? Did I register the route wrong?

Edit: please no comments on my "2 spaces for tabs" indentation - it's a style guide from work, I have no say in it :(

Thanks in advance!

Community
  • 1
  • 1
nbokmans
  • 5,492
  • 4
  • 35
  • 59

1 Answers1

4

First of all, you don't need Route attribute in AdminController, because you registered routes in app.UseMvc() - delete [Route("admin")].

Also, you should change your route in app.UseMvc().

This route:

routes.MapRoute("adminRoute", "Admin/{controller}/{action}/{id?}");

should be changed to:

routes.MapRoute("adminRoute", "{area:exists}/{controller=Admin}/{action=Index}/{id?}");

You need to set area in route and default values for controller and action(it is not necessary to set defaults but it will be explained later in the answer).

So, to call Index() action you should type this url:

http://localhost:yourPortNumber/Admin

Here you make a request to Admin area and default values are used (Admin as default controller and Index as default action). You can change default values for this route.

NOTE: If you didn't set default values in your route then previous link would not work, you should write full url to action - see below.

To call Testing() action url should be:

http://localhost:yourPortNumber/Admin/Admin/Testing

Here you specify area name (Admin), controller name (Admin) and action name (Testing)

By the same way you can call Index() action and other actions (if you need more):

http://localhost:yourPortNumber/Admin/Admin/Index

http://localhost:yourPortNumber/Admin/Admin/AntoherActionName

So, your routes should be configured by this way:

app.UseMvc(routes =>
{
  routes.MapRoute("adminRoute", "{area:exists}/{controller=Admin}/{action=Index}/{id?}");

  routes.MapRoute(
    name: "default",
    template: "{controller=Home}/{action=Index}/{id?}");
});

and your controller:

[Area("Admin")]  
public class AdminController : Controller
{     
  public IActionResult Index()
  {
    return View();
  }

  public IActionResult Testing()
  {
    return Content("Testing area!");
  }
}

EDIT:

You can also can set default area in routes configuration:

routes.MapRoute("adminRoute", "{area=Admin}/{controller=Admin}/{action=Index}/{id?}");

Now when you run your app by default will be used route:

http://localhost:your_port_number/Admin/Admin/Index
Roman
  • 11,966
  • 10
  • 38
  • 47
  • Thank you! This fixed the problem. – nbokmans Feb 15 '17 at 11:28
  • Using the same code above my index action is not called. It gives me "This localhost page can’t be found" error. – Sachin Pakale Mar 29 '17 at 13:13
  • @SachinPakale, are you sure you set correct names for area, controller and action? – Roman Mar 29 '17 at 13:27
  • Yes, the following worked for me - [Route("")] [Route("Admin")] [Route("Admin/Index")] public IActionResult Index() – Sachin Pakale Mar 29 '17 at 14:00
  • @RomaDoskoch but your answer helped me understand the default behavior of app.UseMvc(). Thank you. – Sachin Pakale Mar 29 '17 at 14:09
  • @SachinPakale, you don't need to set `[Route]` attribute at all (you can delete it) , because your routes are configured in `app.UseMvc()`. The answer for the question assumes that your area name is `Admin`, controller name is `AdminController` and action name is `Index` – Roman Mar 29 '17 at 14:23
  • @RomaDoskoch I have added new question if you can help me there. http://stackoverflow.com/questions/43225917/mvc-6-areas-routing-is-not-redirecting-to-the-configured-page – Sachin Pakale Apr 05 '17 at 08:32