2

I defined two controller with same controller name in different namespaces. And got an exception. How to uer parameter "dataTokens" to define namespace of controller like mvc-4?

Exception below:

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

Alice.Controllers.TestController.Index
Alice.Controllers.Api.TestController.Index
Microsoft.AspNet.Mvc.Infrastructure.DefaultActionSelector.SelectAsync(RouteContext context)

Controllers/Api/TestController.cs :

namespace Alice.Controllers.Api
{
    //[Route("api/[controller]")]
    public class TestController : Controller
    {
        //[Route("[action]")]
        public string Index()
        {
            return "this is controller at Alice.Controllers.Api"; ;
        }
    }
}

Controllers/TestController.cs :

namespace Alice.Controllers
{
    //[Route("[controller]")]
    public class TestController : Controller
    {
        //[Route("[action]")]
        public string Index()
        {
            return "this is controller at Alice.Controllers";
        }
    }
}

Startup.cs

        app.UseMvc(routes =>
        {
            routes.MapRoute(
                name: "default",
                template: "{controller}/{action}",
                defaults: null,
                constraints: null,
                dataTokens: new { Namespaces = new[] { "Alice.Controllers" } });

            routes.MapRoute(
                name: "api",
                template: "api/{controller}/{action}",
                defaults: null,
                constraints: null,
                dataTokens: new { Namespaces = new[] { "Alice.Controllers.Api" } });
        });

If more details need please ask.

sui.zhiyuan
  • 23
  • 1
  • 4
  • I would recommend splitting your MVC app from your API app into two different assemblies. – janhartmann Dec 26 '15 at 16:15
  • This is just a demo. It also works with "RouteAttribute", But in Mvc-4 , we can define routing with namespace. There is no reason to delete this function in Mvc-6.@janhartmann – sui.zhiyuan Dec 26 '15 at 16:31

3 Answers3

2

Unfortunately by default you cannot have duplicate controller names in ASPNET MVC Areas (or between an Area and the root of the application). Fortunately, the fix for this is pretty simple, and the exception describes the step you need to take. Once you’ve added an Area, you will have two different places (by default) where routes are defined: one in your root application and one in your area registration. You will want to adjust both of them to specify a namespace parameter. more details check here

Anik Saha
  • 4,313
  • 2
  • 26
  • 41
1

Namespaces are not an MVC feature. Controllers are simply classes. If you need two controllers that are basically the same, then derive them from a common class and put them in whatever namespace you want.

Leonardo Herrera
  • 8,388
  • 5
  • 36
  • 66
1

startUp.cs

app.UseMvc(routes =>
        {
            routes.MapRoute(
                name: "areaRoute",
                template: "{area:exists:regex(^(?!Main$).)}/{controller=Home}/{action=Index}/{id?}");

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

Areas:Main// area default : localhost/home/index

namespace Exzen.Areas.Main.Controllers
{
    [Area("Main")]    
    public class HomeController : Controller
    {
        public IActionResult Index()
        {
            return View();
        }
    }
}

Areas:Test// area plus: localhost/test/home/index

namespace Exzen.Areas.Test.Controllers
{
    [Area("Test")]    
    public class HomeController : Controller
    {
        public IActionResult Index()
        {
            return View();
        }
    }
}