Reputation: 256
I have seen some similar questions but i found that i have a diferent problem.
I have a MVC4 project with controllers in the base project and 3 areas. Each area contains a controller named AdminController and a method List.
My problem is when i use a link to go to method List always go through the same controller (e.g. AdminController in Users area) but the view returned is correct.
The structure of the project is like this:
Classes for area registration contains RegisterArea method like this (with apropiate name and namespace according to the current area):
public override void RegisterArea(AreaRegistrationContext context) {
context.MapRoute(
"Contents_default",
"Contents/{controller}/{action}/{id}",
new { action = "Index", id = UrlParameter.Optional },
new string[] { "Mimbre.Administration.Areas.Contents.Controllers" }
);
}
Global.asax contains method for register routes for base project
public static void RegisterRoutes(RouteCollection routes) {
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
AreaRegistration.RegisterAllAreas();
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional },
namespaces: new string[]{"Mimbre.Administration.Controllers"}
);
}
In index.chtml (in base project) I created links to List method of each area:
<a href="@Url.Action("List", "Admin", new { area = "Contents"})" >Contents list</a>
<a href="@Url.Action("List", "Admin", new { area = "Logs"})" >Logs list</a>
<a href="@Url.Action("List", "Admin", new { area = "Users"})" >Users list</a>
In generated html these links appear like this:
<a href="/Contents/Admin/List/">Contents list</a>
<a href="/Logs/Admin/List/">Logs list</a>
<a href="/Users/Admin/List/">Users list</a>
I think these links are correct, the problem is that any link clicked always takes me through method List in AdminController of Users area, method List in AdminController of another areas are never picked.
This problem could be solved by renaming the name of the controller, unique name for each area, but i really need keep the same controller name in all areas, any idea???
Thans in advance!!!
Upvotes: 0
Views: 4486
Reputation: 762
You need to append one more setting to your route registration. This will prevent the DefaultControllerFactory from searching for controller in unintended areas.
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional },
namespaces: new string[]{"Mimbre.Administration.Controllers"}
).DataTokens["UseNamespaceFallback"] = false;
Upvotes: 0
Reputation: 161
Finally I could simulate your problem. The only way that I could have the same output as you (doens't matter what area you're trying to access, but reaching same users controller and responding with right view) is when you register the Area with the wrong controllers namespaces.
/Admin/Home/List route:
namespace SandboxMvcApplication.Areas.Admin.Controllers
{
public class HomeController : Controller
{
public ActionResult List()
{
ViewBag.Message = "You've acessed Admin/List";
return View();
}
}
}
/Admin/Home/List view:
@{
ViewBag.Title = "List";
}
<h1>Admin</h1>
<h2>@ViewBag.Message</h2>
Admin Area Registration:
public override void RegisterArea(AreaRegistrationContext context)
{
context.MapRoute(
"Admin_default",
"Admin/{controller}/{action}/{id}",
new { action = "Index", id = UrlParameter.Optional },
new string[] { "SandboxMvcApplication.Areas.Admin.Controllers" }
);
}
/User/Home/List route:
public class HomeController : Controller
{
public ActionResult List()
{
ViewBag.Message = "You've accessed User/List";
return View();
}
}
/User/Home/List view:
@{
ViewBag.Title = "List";
}
<h1>User</h1>
<h2>@ViewBag.Message</h2>
User Area registration:
public override void RegisterArea(AreaRegistrationContext context)
{
context.MapRoute(
"User_default",
"User/{controller}/{action}/{id}",
new { action = "Index", id = UrlParameter.Optional },
new string[] { "SandboxMvcApplication.Areas.Admin.Controllers" }
);
}
With this configuration, my outputs are:
/Admin/Home/List
Admin
You've acessed Admin/List
/User/Home/List
User
You've acessed Admin/List
Note that the first word works fine (insuring that the right view was rendered but with wrong data comming from list action).
If I correct the user controller namespace in UserAreaRegistration ("SandboxMvcApplication.Areas.User.Controllers"), everything works fine!
Check it out if this could help you or try to explicitly put your namespaces to the right controller. You could also check if the Admins controller are with the right namespace too.
Upvotes: 2