I have an mvc project and I added a new area with the name BEK
and BEKAreaRegistration.cs was created.
public class BEKAreaRegistration : AreaRegistration
{
public override string AreaName
{
get
{
return "BEK";
}
}
public override void RegisterArea(AreaRegistrationContext context)
{
context.MapRoute(
"BEK_default",
"BEK/{controller}/{action}/{id}",
new { action = "Index", id = UrlParameter.Optional }
);
}
}
and my global.asax file is as follows:
protected void Application_Start()
{
AreaRegistration.RegisterAllAreas();
RouteTable.Routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
RouteTable.Routes.IgnoreRoute("{*allAspx}", new { allAspx = #".*\.aspx(/.*)?" });
RouteTable.Routes.IgnoreRoute("{*allAsmx}", new { allAsmx = #".*\.asmx(/.*)?" });
RouteTable.Routes.IgnoreRoute("{*allAshx}", new { allAshx = #".*\.ashx(/.*)?" });
RouteTable.Routes.IgnoreRoute("Services/{*pathInfo}");
RouteTable.Routes.IgnoreRoute("");
RouteTable.Routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
}
but when i try to go to BEK/Home/Index page I get an error page. What else should I do?
This is the error:
The resource cannot be found. Description: HTTP 404. The resource
you are looking for (or one of its dependencies) could have been
removed, had its name changed, or is temporarily unavailable. Please
review the following URL and make sure that it is spelled correctly.
Requested URL: /LMS_WEB_APP/BEK/Home
-------------------------------------------------------------------------------- Version Information: Microsoft .NET Framework Version:4.0.30319;
ASP.NET Version:4.0.30319.18213
When you add BEK Area.
MVC will create These for you.
Mvc will not create any Controller and Actions and Views.
So, you do have to do that manually that which controllers, actions and views you want to add.
So, now you do have to Add the Controller by Right Clicking on Controller and Add Controller.
After Adding the Controller.
You can do right click on the Action and Add View like this to add the View :
Ok....
So, you do have Both Controller and Action and Views required.
Now you might have to Resolve the Controller Duplicacy, if any, which i had told you earlier.
Happy Coading...
I think problem is that, You have Same Name controller in Both Area and and application. Like You have Home Controller in Normal Application and Also in AREA
And, it is causing the Duplicate Declaration of Same Controller.
The way doing that is, specifying the NAMESPACE of the Controller Like the Following :
public override void RegisterArea(AreaRegistrationContext context)
{
context.MapRoute(
"BEK_default",
"BEK/{controller}/{action}/{id}",
new { action = "Index", id = UrlParameter.Optional },
new string[] { "MyAppName.Areas.BEK.Controllers" } // specify the new namespace
);
}
If not that Case, Please post the Error Message you are getting.
Related
I already have controllers and views in folders under the project name. I added an Area folder and then an area inside it and called it Home and then moved my controller and index view into it. But when I connect to the index I get an error and it looks like the path where it's looking for the index is the old path, how do I change this to the new path?
Here is what I created
In 'HomeAreaRegistration' I see this under RegstrationArea
public class HomeAreaRegistration : AreaRegistration
{
public override string AreaName
{
get
{
return "Home";
}
}
public override void RegisterArea(AreaRegistrationContext context)
{
context.MapRoute(
"Home_default",
"Home/{controller}/{action}/{id}",
new { action = "Index", id = UrlParameter.Optional }
);
}
}
But when I run the application in IE, here is what I see in the browser! It looks like it's looking for the index.cshtml in the old path location, not the new path location in the new area 'Home'
It looks like the route engine is looking in the wrong location. So here is what my RouteConfig.cs file looks like.
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
Even when I try 'https://localhost:44301/Home/Index.cshtml' it throws a HTTP 404 error.
The 404 error shows the main problem itself: default routing and view engine search cannot found default Index.cshtml view file in Views directory on your project (i.e. ProjectName/Views/Index.cshtml pointed by route ~/Views/Home/Index).
First, create a class to include view location search for your custom area like this example:
public class CustomView : RazorViewEngine
{
public CustomView()
{
MasterLocationFormats: new[]
{
"~/Areas/Home/Views/{0}.cshtml",
"~/Areas/Home/Views/{1}/{0}.cshtml"
}
ViewLocationFormats: new[]
{
"~/Areas/Home/Views/{0}.cshtml",
"~/Areas/Home/Views/{1}/{0}.cshtml"
}
PartialViewLocationFormats = ViewLocationFormats;
FileExtensions = new[]
{
"cshtml"
};
}
}
Then, include all areas and your custom view engine into Global.asax:
protected void Application_Start()
{
// register all area locations
AreaRegistration.RegisterAllAreas();
// clear default view engine
ViewEngines.Engines.Clear();
// add your custom view engine here
// the custom view engine should loaded before default view engine (e.g. Razor)
ViewEngines.Engines.Add(new CustomView());
ViewEngines.Engines.Add(new RazorViewEngine());
}
If you have RouteConfig class on App_Start directory, make sure RegisterAllAreas has included before default route:
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 }
);
}
Additionally, add namespace of the controller name when required or the above solution still doesn't work:
public class HomeAreaRegistration : AreaRegistration
{
public override string AreaName
{
get
{
return "Home";
}
}
public override void RegisterArea(AreaRegistrationContext context)
{
context.MapRoute(
"Home_default",
"Home/{controller}/{action}/{id}",
new { action = "Index", id = UrlParameter.Optional },
namespaces: new[] { "ProjectName.Areas.Home.Controllers" }
);
}
}
NB: Create Home directory under Views if you want to follow route convension ~/Areas/Views/Home/Index, and put Index.cshtml file into it.
References:
How to set a Default Route (To an Area) in MVC
How to register areas for routing
your area folder structure look like this
Reister your area in Global.asax
AreaRegistration.RegisterAllAreas();
and try with this url
http://localhost:44301/Home/Home/Index
you have to do below corrections in your solution:
1) Add a Folder Home in Views and place index.cshtml in it.
Folder structure for view must be: Home(Area name) > Views > Home (same name as controller) > index.cshtml (as shown in picture)
2)change namespace of your Homecontroller to (Solution name).Areas.Home.Controllers
3)Also you have to refer following route pattern for area:
localhost/AreaName/Controller/Action
which in your case:
https://localhost:44301/Home/Home/Index
Hope this might solve your problem
By default Areas have a /Area/ routing prefix. For instance a Blog area would be :
/Areas/Blog/Blog/Show/myId
or
/Areas/{area}/{controller}/{action}/{id}
The result is a really ugly and redundent uri for the web application. What I would like is something along the lines of :
/Blog/Show/myId
or
/{area / controller}/{action}/{id}
How can I achieve this ?
The reason I am using areas is because my 'blog' area is not a standard MVC application, but, a single-page application. It has a different project structure than the rest of the app, and so, I would like to just partition it into its own area.
Edit : source for Area Registration
public class BlogAreaRegistration : AreaRegistration
{
public override string AreaName
{
get
{
return "Blog";
}
}
public override void RegisterArea(AreaRegistrationContext context)
{
context.MapRoute(
"Blog_default",
"Blog/{action}/{id}",
new { controller ="blog", action = "Index", id = UrlParameter.Optional }
);
}
}
Edit Source for Routeing
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
Edit
After speaking /u/Eric Philips I have come up with a solution. The solution was rework my file structure to MVC compatible. Once I setup a controller and moved my index.cshtml page into a valid location, /Blog/ worked fine.
public class BlogController : Controller
{
// GET: Blog/Blog
public ActionResult Index()
{
return View();
}
}
I have a project with 2 areas. Its does work but I am a newbie to this and I want to understand why.
I have an Area called LogonArea
context.MapRoute(
"LogonArea_default",
"LogonArea/{controller}/{action}/{id}",
new { action = "Index", id = UrlParameter.Optional }
Why is the 'LogonArea/' part needed? Shouldn't it be able to find the controller without it?
When I tried removing it I could still reach controllers with that Area but strangely I couldn't reach other areas while on that page.
If this is really necessary how could I mask it so the Area wasn't visible in the url?
thanks
If you remove /LoginArea/ from the area route registration, it will be able to find your controller (as long as you don't have any conflicting controller names such as HomeController in the main section and HomeController in the area).
It's mainly there for your convenience. If you have an Admin area, everything in your site will be accessible via /Admin/{controller}. It's mostly just an organizational thing.
public class AdminAreaRegistration : AreaRegistration
{
public override string AreaName
{
get
{
return "Admin";
}
}
public override void RegisterArea(AreaRegistrationContext context)
{
context.MapRoute(
"Admin_default",
"{controller}/{action}/{id}",
new { action = "Index", id = UrlParameter.Optional }
);
}
}
I created a single controller called FooController in this project, and I was able to go to the url /Foo to reach it without needing to go to /Admin/Foo
When you create a link to a controller outside of the area you need to specify which area it's in (or specify that there is no area):
#Html.ActionLink("Go Home", "Index", "Home", new { area = "" }, null)
I have added a new Area to my MVC3 project and I am trying to link from the _Layout page to the new Area. I have added an Area called 'Admin' that has a controller 'Meets'.
I used the visual studio designer to add the area so it has the correct area registration class etc, and the global.asax file is registering all areas.
However, when I use the following 2 action links in a page in the root, I run into a few problems:
#Html.ActionLink("Admin", "Index", "Meets", new { area = "Admin" }, null)
#Html.ActionLink("Admin", "Index", "Meets", new { area = "" }, null)
When clicking both links, I am taken to the Meets controller in the Admin area, where the application then proceeds to throw an error saying it cannot find the Index page (even though the Index page is present in the Views folder in the Area sub-directory.
The href for the 1st link looks like this:
http://localhost/BCC/Meets?area=Admin
And the href for the 2nd link looks like this:
http://localhost/BCC/Meets
Also if I hit the link that I expect to be created:
http://localhost/BCC/Admin/Meets
I just get a resource cannot be found error. All very perplexing! I hope someone can help...
Strange indeed. Steps that worked perfectly fine for me:
Create a new ASP.NET MVC 3 application using the default Visual Studio template
Add an area called Admin using Visual Studio designer by right clicking on the project
Add new Controller in ~/Areas/Admin/Controllers/MeetsController:
public class MeetsController : Controller
{
public ActionResult Index()
{
return View();
}
}
Add a corresponding view ~/Areas/Admin/Views/Meets/Index.cshtml
In the layout (~/Views/Shared/_Layout.cshtml) add links:
#Html.ActionLink("Admin", "Index", "Meets", new { area = "Admin" }, null)
#Html.ActionLink("Admin", "Index", "Meets", new { area = "" }, null)
Run the application.
Rendered HTML for the anchors:
Admin
Admin
As expected the first link works whereas the second doesn't.
So what's the difference with your setup?
Another option is to utilize RouteLink() instead of ActionLink(), which bypasses the area registrations altogether:
ActionLink version:
Html.ActionLink("Log Off", "LogOff", "Account", new { area = "" }, null)
RouteLink version:
Html.RouteLink("Log Off", "Default",
new { action = "LogOff", controller = "Account" })
The second parameter is a "Route Name" which is registered in Global.asax.cs and in various 'AreaRegistration' subclasses. To use 'RouteLink' to link between different areas, you only need to specify the correct route name.
This following example shows how I would generate three links to different areas from a shared partial, which works correctly regardless of which area I am 'in' (if any):
#Html.RouteLink("Blog", "Blog_default",
new { action = "Index", controller = "Article" })
<br/>
#Html.RouteLink("Downloads", "Download_default",
new { action = "Index", controller = "Download" })
<br/>
#Html.RouteLink("About", "Default",
new { action = "Index", controller = "About" })
Happy coding!
I figured this out - I created a new test project and did exactly the same thing I was doing before and it worked...then after further inspection of all things route-related between the two projects I found a discrepancy.
In the global.asax file in my BCC application, there was a rogue line of code which had inexplicably appeared:
public static void RegisterRoutes(RouteCollection routes)
{
// Problem here
routes.Clear();
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapRoute(
"Default", // Route name
"{controller}/{action}/{id}", // URL with parameters
new { controller = "Home", action = "Index", id = UrlParameter.Optional } // Parameter defaults
);
}
protected void Application_Start()
{
AreaRegistration.RegisterAllAreas();
RegisterGlobalFilters(GlobalFilters.Filters);
RegisterRoutes(RouteTable.Routes);
}
As you can see where my comment is, at some time or other I had placed the routes.Clear() call at the beginning of RegisterRoutes, which meant after I had registered the Areas in Application_Start, I was then immediately clearing what I had just registered.
Thanks for the help...it did ultimately lead to my salvation!
Verify that your AdminAreaRegistration class looks like this:
public class AdminAreaRegistration : AreaRegistration
{
public override string AreaName
{
get
{
return "Admin";
}
}
public override void RegisterArea(AreaRegistrationContext context)
{
context.MapRoute(
"Admin_default",
"Admin/{controller}/{action}/{id}",
new { action = "Index", id = UrlParameter.Optional }
);
}
}
and that you have this in Global.asax.cs:
protected void Application_Start()
{
... // ViewEngine Registration
AreaRegistration.RegisterAllAreas();
... // Other route registration
}
I solved this problem by doing the following.
In my Global.asax.cs, I have
public static void RegisterGlobalFilters(GlobalFilterCollection filters)
{
filters.Add(new HandleErrorAttribute());
}
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.IgnoreRoute("{*favicon}", new { favicon = #"(.*/)?favicon.ico(/.*)?" });
}
protected void Application_Start()
{
//Initialise IoC
IoC.Initialise();
AreaRegistration.RegisterAllAreas();
RegisterGlobalFilters(GlobalFilters.Filters);
RegisterRoutes(RouteTable.Routes);
}
In my PublicAreaRegistration.cs (Public Area), I've got
public class PublicAreaRegistration : AreaRegistration
{
public override string AreaName
{
get
{
return "Public";
}
}
public override void RegisterArea(AreaRegistrationContext context)
{
context.MapRoute("Root", "", new { controller = "Home", action = "Index" });
context.MapRoute(
"Public_default",
"Public/{controller}/{action}/{id}",
new { controller = "Home", action = "Index", id = UrlParameter.Optional }
, new[] { "<Project Namespace here>.Areas.Public.Controllers" }
);
}
}
In my AuthAreaRegistration.cs (Area for Restricted access), I've got
public class AuthAreaRegistration : AreaRegistration
{
public override string AreaName
{
get
{
return "Auth";
}
}
public override void RegisterArea(AreaRegistrationContext context)
{
context.MapRoute(
"Auth_default",
"Auth/{controller}/{action}/{id}",
new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
}
}
And finally, my links in my *.cshtml pages would be like
1) #Html.ActionLink("Log Off", "LogOff", new{area= "Public", controller="Home"})
or
2) #Html.ActionLink("Admin Area", "Index", new {area= "Auth", controller="Home"})
Hope this saves someone hours of research! BTW, I'm talking about MVC3 here.
Kwex.
This might not be the case for most of the developers but I encountered this problem when I added a my first area and did not build my solution. As soon as I build my solution the links started to populate correctly.
I am in the process of debugging a routing issue on my MVC 3 application and I am using Phil Hacks routing debugger.
I cannot seem to work out where the route highlighted in yellow below is originating. Each time I run my application with the following request
http://www.mywebsite.com/auth/login?ReturnUrl=/
this route comes first and then gives me a 404 error as I do not have an index action. As you can see I have set my default routes to use the Login action method but still this route persists.
I have the following route configurations:
AuthAreaRegistration
public class AuthAreaRegistration : AreaRegistration
{
public override string AreaName
{
get
{
return "Auth";
}
}
public override void RegisterArea(AreaRegistrationContext context)
{
context.MapRoute(
"login",
"auth/login/{*returnPath}",
new { controller = "Auth", action = "LogIn", id = UrlParameter.Optional }
);
context.MapRoute(
"Auth_default",
"Auth/{controller}/{action}/{id}",
new { controller = "Auth", action = "LogIn", id = "" }
);
}
}
Global.asax (Using T4 MVC Templates)
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapRoute(
"Home",
"{controller}/{action}/{id}",
MVC.Home.Index(), new { id = UrlParameter.Optional },
new string[] { "MyNamespace.WebUI.Controllers" }
);
routes.MapRoute(
"Default",
"{controller}/{action}/{id}",
MVC.Home.Index(), new { id = UrlParameter.Optional },
new string[] { "MyNamespace.WebUI.Controllers" }
);
}
I don’t like to answer my own question but after a day of trying to solve this problem I thought I would post the answer in case anyone else has the same issue.
It turns out that my application was holding onto old routes and populating them into my route collection. I deleted all the files in my bin folder and rebuilt my solution and everything worked as it should.
I have answered this question in a little more detail here:
Does ASP.NET MVC create default routes for areas
I think the problem is in the fact that you have an area called Auth and a controller called Auth outside of the areas.
MVC will try to match your url against Auth area first but you actually want it to hit your auth controller outside an area.
The best way to solve it imho is to avoid a ambiguous names of controllers/areas.