I have multiple controllers one in Areas
/Areas/Demo/Admin/AdminController
and other in main site
/Controller/Admin/AdminController
Now getting error
Multiple types were found that match the controller named 'Admin'.
How to resolve the issue? Better if I can change something in Areas/Demo as I have to use same Areas on multiple sites.
Define namespace in your route. http://msdn.microsoft.com/en-us/library/dd492682.aspx
For example my area "Admin" is mapped like this:
context.MapRoute(
"Admin_default",
"Admin/{controller}/{action}/{id}",
new { controller = "Home", action = "Index", id = UrlParameter.Optional },
new string[] { "MvcBase.Areas.Admin.Controllers" }
);
Related
I have an MVC Application as follows:
Application
Controllers
HomeController
ActionResult Index();
Areas
IT
Controllers
ITHomeController
ActionResult Index();
I have setup the links to work correctly between the main application and the IT Area.
In the URL the link to the IT area shows up as http://localhost/IT/ITHome.
The code for the link is:
#Html.ActionLink("IT Page","Index","ITHome", new { area = "IT" }, null)
How would I have the url simply be http://localhost/IT I'm sure it's simple.
Thanks!
Look for /Areas/IT/ITAreasRegistration.cs
Add a route mapping in its public override void RegisterArea(AreaRegistrationContext context) method, preferably at the very top or at least before the default route for the area.
Something like:
context.MapRoute(
"default_IT",
"IT",
new { action = "Index", controller = "ITHome" },
new[] { "YourAppNamespaceHere.Areas.IT.Controllers" }
);
As for the link... I'd just hand code it to IT Home and be done with it unless you are hosting this as a sub application from the wwwroot, you should be fine.
In this way you can keep your area routes separate from your normal routes.
Renaming the ITHomeController to HomeController may give you ambiguous matching.
You could change the registered route mapping e.g. add a new route that has ITHOME as the default controller if the area matches IT.
routes.MapRoute(
"ITHome",
"IT/{controller}/{action}/{id}",
new { area = "IT", controller = "ITHome", action = "Index", id = UrlParameter.Optional }
);
Then, just for the IT area, it will allow the default controller to be your ITHomeController.
I have 3 areas at the moment (more will come when I get this working): Login, User and Admin. The Default route in Global.asax go to the index action of the index controller in the login area (Login\Index\Index) which works fine, this is how I mapped that:
routes.MapRoute(
"Default", // Route name
"{area}/{controller}/{action}/{id}", // URL with parameters
new { area = "Login", controller = "Index", action = "Index", id = UrlParameter.Optional }, // Parameter defaults
new[] { typeof(AppName.Areas.Login.Controllers.IndexController).Namespace }
);
each of the 3 areas is registered like this in the AreaRegistration files:
context.MapRoute(
"Admin_default",
"{area}/{controller}/{action}/{id}",
new { area = "Admin", controller = "Index", action = "Index", id = UrlParameter.Optional },
new[] { typeof(AppName.Areas.Admin.Controllers.IndexController).Namespace }
);
The Login controllers index action takes the users login details, looks up the type of user and redirects them to the appropriate area...... at least it should do. From what I can gather searching google, the correct way to redirect to a specific area is this:
return RedirectToAction("Action", "Controller", new { area = UserType });
which doesn't seem to work, it just redirects to Login\Controller\Action and I can't work out why.
In my attempts to work out what was happening I used this:
var url = Url.Action("Action", "Controller", new { area = "Admin" });
which produced the same Login\Controller\Action url.
Any help fixing this would be greatly appreciated
In the routes parameter, you just set new { area = "OtherAreaName" }.
EDIT
Oh, I see you already tried that. I suppose the name of that area is correctly referenced and correctly named in the class AreaRegistration class, like this?
public class AuthorAreaRegistration : AreaRegistration
{
public override string AreaName
{
get
{
return "Author";
}
}
// ...
}
Could it also be that you need authentication and you are being redirected to the login page?
I've got an Area in my web app called "Admin".
So, http://localhost.com/Admin goes to the Home Controller and Index Action in the Admin Area.
However, I want to be able to hit the Admin Home Controller and Index Action with the following Url:
http://localhost.com/Hello
I've got this as my attempt:
routes.MapRoute(
"HelloPage",
"Hello/{controller}/{action}",
new{area= "Admin", controller = "Home", action = "Index"},
new[] { typeof(Areas.Admin.Controllers.HomeController).Namespace });
As you can see I'm specifying the namespace and the area, but all I get is the routing error:
The view 'Index' or its master was not found or no view engine supports the searched locations.
It's not searching in the Admin area.
Any ideas?
Try this:
routes.MapRoute(
"HelloPage",
"Hello/{controller}/{action}/{id}",
new { area = "Admin", controller = "Home", action = "Index", id = UrlParameter.Optional }
);
And then add this to your Admin controller action:
if (!this.ControllerContext.RouteData.DataTokens.ContainsKey("area"))
{
this.ControllerContext.RouteData.DataTokens.Add("area", "Admin")
}
You can check here for further documentation.
The problem was that I was setting the route in Global.asax.
I should have been setting it in the AreaRegistration in the Admin area. Once I did that the problem was fixed.
I have two very simple routes
routes.MapRoute(
"post", // Route name
postPage + "/{slug}", // URL with parameters
new { controller = "Home", action = "Article" } // Parameter defaults
);
routes.MapRoute(
"page", // Route name
"{slug}", // URL with parameters
new { controller = "Home", action = "Page", slug = homePage} // Parameter defaults
);
And here is my controller logic
public ActionResult Article(string slug)
{
return View(repo.GetPost(slug));
}
public ActionResult Page(string slug)
{
if (slug.ToLower() == MetaData.PostsPage.ToLower())
return View("listPosts", repo.GetAllPosts());
else
return View("page", repo.GetPage(slug));
}
homePage and postPage are set from value's in the database. Allowing the user to define the default page as well as the page to show posts.
My issue occurs when adding an area named "Admin". I get a controller added to my RouteTable
context.MapRoute(
"Admin_default",
"Admin/{controller}/{action}/{id}",
new { action = "Index", id = UrlParameter.Optional }
);
Now when a user Access Admin/Account/Logon the page loads fine, but my debugger still tries to go into the Home controller and the Page action. But the RouteDebugger says it doesn't match the current request. I'm puzzled on how to fix this.
RouteDebugger screenshot: http://i.stack.imgur.com/7cpHm.png
Debugger going into my HomeControler Page AtionResult: http://i.stack.imgur.com/uSJBK.png
Actually the problem is, Area routes are overriding the global routes, to distinguish both the routes set the relevant namespace of area's controller in the context.MapRoute method in adminAreaRegistraton.cs file. i.e.
context.MapRoute(
"admin_default",
"admin/{controller}/{action}/{id}",
new { controller = "Home", action = "Index", id = UrlParameter.Optional },
null,
new string[] { "MVCApplication1.Areas.admin.Controllers" }
);
I found out the issue.
I had a favicon.ico set in the main area of my site, but not the Admin area.
So when I went to the Admin area the browser made a request for favicon.ico that got picked up by that route. Thats why my routes looked fine in the RouteDebugger, because they were.
Thanks for the help Kundan!
Today I've started restructuring my mvc project using areas. So I have some problems with it.
I make areas, move views and master pages, make routing, but when I'm trying to view any area page I get "The view 'Login' or its master could not be found."
Any suggestions? I've googled for some time, but didn't found any solution.
My global.asax routing:
routes.MapRoute("Areaname", "Areaname",
"Areaname/{controller}/{action}/{id}",
new { controller = "controllerName", action = "Home", id = UrlParameter.Optional },
new string[] { "path.to.area.controllers.Controllers" });
Area registration routing:
public override void RegisterArea(AreaRegistrationContext context)
{
context.MapRoute(
"Areaname_default",
"Areaname/{controller}/{action}/{id}",
new { action = "Home", id = UrlParameter.Optional },
new string[] { "path.to.area.controllers.Controllers" }
);
}
It seems to be correct, but views are still unavailable.
Thanks in advance.
When using Areas, make sure you rewrite your action links like this:
Html.ActionLink("Invoicing link", "Index", "CustomerInvoices", new { area = "Invoicing" }, null)
In this example, you are linking to the "Index" action, inside "CustomerInvoices" controller, inside "Invoicing" Area.
Make sure you do the proper modifications to link to the Login action inside your Area!