I have created a area named "User" in my mvc project. So now i can access that area using the url mysite.com/user.
Now can i change the name of the area in url ? i want to access my area using the url mysite.com/admin
I can do this by changing the folder name of the "user" area. But i need to modify lot of files if i change my folder name. So is there any other way to show different name in url ? using areaRegistration.cs ?
In your UserAreaRegistration file set up something like this:
public class UserAreaRegistration : AreaRegistration
{
public override string AreaName
{
get
{
return "admin";
}
}
public override void RegisterArea(AreaRegistrationContext context)
{
context.MapRoute(
"Admin_default",
"Admin/{controller}/{action}/{id}",
new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
}
}
And point to the controller/action etc that you want.
Related
I am having trouble with rendering URL addresses after changing routing.
Routing Configuration
public class AccountArea : AreaRegistration
{
public override void RegisterArea(AreaRegistrationContext context)
{
context.MapRoute(
"Account",
"Account/{controller}/{action}/{id}",
new { controller = "User", action = "Index", id = UrlParameter.Optional },
namespaces: new[] {
"Application.Controllers.Account"
}
);
}
public override string AreaName => "AccountArea";
}
public class FrontArea : AreaRegistration
{
public override void RegisterArea(AreaRegistrationContext context)
{
context.MapRoute(
"Front",
"{controller}/{action}/{id}",
new { controller = "Home", action = "Index", id = UrlParameter.Optional },
namespaces: new[] {
"Application.Controllers.Front"
}
);
}
public override string AreaName => "FrontArea";
}
and RouteConfig:
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
}
Controllers
// on folder Controllers/Front/
namespace Application.Controllers.Front
class HomeController : Controller
{
ActionResult Index(){ ... }
}
// on folder Controllers/Account/
Application.Controllers.Account
class UserController : Controller
{
ActionResult Index(){...}
}
I have changed routing because I want to separate the controllers into 2 subfolders, Front and Account.
This configuration allows me to divide the application into 2 parts, differentiated by using URL address.
localhost/Home/Index [namespace: Application.Controllers.Front]
localhost/Account/User/Index- [namespace: Application.Controllers.Account]
after entering the address to the browser
localhost/Home/Index - will start method Index from HomeController
localhost/Account/User/Index - will start method Index from UserController
A problem appears when on URL address localhost/Home/Index and I try rendering URL address belonging to localhost/Account/User/Index.
When I use #Url.Action("Index","User") address will be rendered, but without the "Account" prefix in the URL.
I receive: /User/Index
But, I expect: /Account/User/Index
And vice versa, on localhost/Account/User/Index I can't render correct URL address belonging to localhost/Home/Index.
This problem I can solve using Url.RouteUrl like
#Url.RouteUrl("Account", new {controller = "User", account = "Index"} )
but, this requires route name, which I don't want to provide.
When using Area routes, all of the UrlHelper URL resolution methods (such as ActionLink or Url.Action) will use the same area by default.
Linking from Front Area to Front Area
#Url.Action("Index", "User")
To specify to go to a different area, you must explicitly specify the area in the route values that are passed in to Url.Action.
Linking from Front Area to Account Area
#Url.Action("Index", "User", new { area = "Account" })
The same goes for links generated inside of the Account area. You will need to explicitly override the current area name with Front.
Linking from Account Area to Front Area
#Url.Action("Index", "User", new { area = "Front" })
this requires route name, which I don't want to provide.
Option 1 - Use Constants for Areas
Make a set of constants that you use for all of your area strings in the application.
public static class Areas
{
public const string Front = "Front";
public const string Account = "Account";
}
And use like
#Url.Action("Index", "User", new { area = Areas.Front })
Option 2 - Use T4MVC
There is a package called T4MVC that generates constants for your project so you can replace routing and URL generation without using magic strings.
#Url.Action(MVC.Areas.Front.User.Index)
Option 3 - Use Extension Methods
Another option would be to build your own extension methods to replace Url.Action, Html.ActionLink, RedirectToAction, etc.
#Url.ActionToFront("Index", "User")
This is a lot of action methods to create, though.
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
I am trying to achieve the routings as follow:
http://example.com/Admin/Index
http://example.com/Application/Index
http://example.com/Customers/Index
etc...
I like the ideas of using 'Areas' and want to separate all the codes by using Areas. So, I created my Areas structure like the following screnshot
and the code in ApplicationAreaRegistration.cs is
public override string AreaName
{
get
{
return "Application";
}
}
public override void RegisterArea(AreaRegistrationContext context)
{
context.MapRoute(
"Application_default",
"Application/{controller}/{action}/{id}",
new { action = "Index", id = UrlParameter.Optional }
);
}
However, I cannot achieve the route I want like
http://example.com/Application/Index
In stead of that it becomes, http://example.com/Application/Application/Index
I tried to change the default routing without {controller} in AreaRegistration
context.MapRoute(
"Application_default",
"Application/{action}/{id}",
new { action = "Index", id = UrlParameter.Optional }
);
But I got, Controller is required area.
I know I can easily get http://example.com/Application/Index if I put the Controller in root Controllers Folder. But it means I couldn't group my codes like the Areas anymore and it will be seprated across the MVC Folders.
What I would like to know is, whether I can achieve what I want by using the Areas or am I trying to do which is impossible?
You need to add a default controller name to the route so MVC understands what to put in the controller route value when you take it out of the URL.
public override void RegisterArea(AreaRegistrationContext context)
{
context.MapRoute(
"Application_default",
"Application/{action}/{id}",
new { controller = "Application", action = "Index", id = UrlParameter.Optional }
);
}
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)