I created an Area in MVC then I created a simple controller and I can't view the Area or any page within that part of my site does anyone know why and how to fix this problem. I created a project a while back with an Area and had no problems, I don't know what has changed or if I had to change something to make it work can somebody please help me out.
Somewhere it's not getting registered.
namespace RedPlanet.Areas.admin.Controllers
{
public class CategoryController : Controller
{
}
}
Area:
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 }
);
}
}
Global ASAX:
public class MvcApplication : System.Web.HttpApplication
{
protected void Application_Start()
{
AreaRegistration.RegisterAllAreas();
WebApiConfig.Register(GlobalConfiguration.Configuration);
FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
RouteConfig.RegisterRoutes(RouteTable.Routes);
BundleConfig.RegisterBundles(BundleTable.Bundles);
AuthConfig.RegisterAuth();
System.Data.Entity.Database.SetInitializer(new System.Data.Entity.DropCreateDatabaseIfModelChanges<DataContext>());
}
}
You need to specify the namespace when registering the route for your admin area and Main Route in you Application.
Main Route :
routes.MapRoute(
"Default",
"{controller}/{action}/{id}",
new { controller = "Home", action = "Index", id = UrlParameter.Optional },
new string[] { "RedPlanet.Controllers" }// specify the namespace
);
In your \Areas\admin\adminAreaRegistration.cs file, you need to modify the RegisterArea() method as follows:
public override void RegisterArea(AreaRegistrationContext context)
{
context.MapRoute(
"admin_default",
"admin/{controller}/{action}/{id}",
new { action = "Index", id = UrlParameter.Optional },
new[] { "RedPlanet.Areas.admin.Controllers" }// specify the namespace
);
}
Update :
if you are using Guid you should change parameter type of your action method to Guid :
public ActionResult Details(Guid guid)
{
//code
return View(model);
}
then create new route for that ;
routes.MapRoute("FooRouteName",
"Controller/Action/{guidParam}",
new { controller = "Category", action = "Index" },
new { guidParam = #"^(\{){0,1}[0-9a-fA-F]{8}\-[0-9a-fA-F]{4}\-[0-9a-fA-F]{4}\-[0-9a-fA-F]{4}\-[0-9a-fA-F]{12}(\}){0,1}$" }
);
Related
I have two different Areas (User & Report) and they have two views (Login & Index) respectively.
What I am trying to do is on successful login user should be redirected to Report/Index page but its not working.
Its always inside User area only. Can some one point out what needs to be corrected here. Thanks!!! Help will be appreciated...
public class UserController : Controller
{
[HttpGet]
public ActionResult Login()
{
return View();
}
[HttpPost]
public ActionResult Login(Models.User user)
{
if (ModelState.IsValid)
{
if (user.IsValid(user.UserName, user.Password))
{
return RedirectToAction("Report/Report/Index");
}
else
{
ModelState.AddModelError("", "Login data is incorrect!");
}
}
return View(user);
}
}
public class ReportController : Controller
{
// GET: Report/Report
public ActionResult Index()
{
return View();
}
}
public class RouteConfig
{
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "User", action = "Login", id = UrlParameter.Optional },
namespaces: new[] { "DWP_MVC.Areas.User.Controllers" }
).DataTokens.Add("area", "User");
routes.MapRoute(
name: "Report",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Report", action = "Index", id = UrlParameter.Optional },
namespaces: new[] { "DWP_MVC.Areas.Report.Controllers" }
).DataTokens.Add("area", "Report");
}
}
public override void RegisterArea(AreaRegistrationContext context)
{
context.MapRoute(
"User_default",
"User/{controller}/{action}/{id}",
new { action = "Login", id = UrlParameter.Optional }
);
}
public override void RegisterArea(AreaRegistrationContext context)
{
context.MapRoute(
"Report_default",
"Report/{controller}/{action}/{id}",
new { action = "Index", id = UrlParameter.Optional }
);
}
Your RedirectToAction() call must include the area name if you are using areas in your MVC structure.
In your example the following code would work:
return RedirectToAction("Index", "Report", new { area = "Report" });
As an aside, if you wish to redirect from one area to a controller/view which is not within the Area folder, you can utilize area = ""
I'm not sure if this is possible using mvc routing, I haven't been able to find a similar example.
I have about 5~ controller actions that are the same method, so I'd like to refactor them into a single action. I'd like to pass an enum value to the controller to tell it what path it should pass to lower layers.
Example:
public ActionResult ViewPage(int id, PageEnum page) {
var model = MyService.GetModelForTemplate(id, page);
return ("ViewPage", model);
}
Then the user could access this either through /PagesTypeOne/ViewPage/, or /PagesTypeTwo/ViewPage/. Both routes leading to the same endpoint.
Route table attempt:
routes.MapRoute(
name: "typeOne",
url: "PagesTypeOne/{action}/{id}",
defaults: new { controller = "Pages", action = "ViewPage", id = UrlParameter.Optional, page = PageEnum.TypeOne, }
);
routes.MapRoute(
name: "typeTwo",
url: "PagesTypeTwo/{action}/{id}",
defaults: new { controller = "Pages", action = "ViewPage", id = UrlParameter.Optional, page = PageEnum.TypeTwo, }
);
This obviously isn't working.
Is there a way I can do something like this? It would make my code much more concise.
screen != page, so if the property on the anonymous type matches the parameter it will work:
public ActionResult ViewPage(int id, PageEnum screen) {
var model = MyService.GetModelForTemplate(screen);
return ("ViewPage", model);
}
Updated: Created a empty application and it work flawlessly:
namespace MvcApplication6
{
public class MvcApplication : System.Web.HttpApplication
{
public static void RegisterGlobalFilters(GlobalFilterCollection filters)
{
filters.Add(new HandleErrorAttribute());
}
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapRoute(
"Test1",
"PagesTypeOne/{action}/{id}", // URL with parameters
new { controller = "Home",
action = "Index",
id = UrlParameter.Optional,
page = PageEnum.PageOne } // Parameter defaults
);
routes.MapRoute(
"Test2",
"PagesTypeTwo/{action}/{id}", // URL with parameters
new { controller = "Home",
action = "Index",
id = UrlParameter.Optional,
page = PageEnum.PageOne } // Parameter defaults
);
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);
}
}
}
public enum PageEnum
{
Undefined,
PageOne,
PageTwo
}
Controller:
namespace MvcApplication6.Controllers
{
public class HomeController : Controller
{
public ActionResult Index()
{
return View();
}
public ActionResult ViewPage(int id, PageEnum page)
{
var debug = 1; // break point
return new EmptyResult();
}
}
}
you can make it completely dynamic with one route definition:
// the route must be defined as the first route
routes.MapRoute(
name: "typeTwo",
url: "{page}/ViewPage/{id}",
defaults: new { controller = "Pages", action = "ViewPage", id = UrlParameter.Optional },
new { page= getPageTypes() }
);
the getPageTypes method:
private static string getPageTypes()
{
var pageTypes = Enum.GetNames(typeof(PageEnum));
return string.Join("|", pageTypes );
}
but PagesTypeOne/ViewPage/4 part must match the enum's name.
The director below keeps redirecting to my homepage (Home/Index). I'm not sure why, but I have other areas created called Coaches and Directors, and they work fine. Fiddler only shows a 302 from that dashboard action to the homepage. If I go to /athletes/dashboard/index it works fine.
public virtual ActionResult Dashboard()
{
return RedirectToAction(MVC.Athletes.Dashboard.Index());
}
Global.asax
routes.MapRoute(
"Default",
"{controller}/{action}",
new { controller = "Home", action = "Index", area="" },
new[] { "Tournaments.Controllers", "Tournaments.Controllers.Api" }
);
Area
namespace Tournaments.Areas.Athletes
{
public class AthletesAreaRegistration : AreaRegistration
{
public override string AreaName
{
get
{
return "Athletes";
}
}
public override void RegisterArea(AreaRegistrationContext context)
{
context.MapRoute(
"Athletes",
"athletes",
new { action = "Index", controller = "Dashboard", bodyclass = "members" },
new[] { "Tournaments.Areas.Athletes.Controllers" }
);
context.MapRoute(
"Athletes_Dashboard",
"athletes/dashboard/{action}",
new { action = "Index", controller = "Dashboard" },
new[] { "Tournaments.Areas.Athletes.Controllers" }
);
context.MapRoute(
"Athletess_Default",
"athletes/{controller}/{action}",
new { action = "Index", controller = "Dashboard" },
new[] { "Tournaments.Areas.Athletes.Controllers" }
);
}
}
}
Found the issue, I was calling a URL from the coaches area from an ajax request, and it was causing a redirect from the page because the user wasnt in the coach role, and because I had a URL redirect from the Rewrite Module, blah.
I have an MVC 4 web application which consists some areas. I have a problem with the routing rules of an area named "Catalog". The RouteConfig.cs file is:
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional },
);
}
and Global.asax as follows:
protected void Application_Start()
{
AreaRegistration.RegisterAllAreas();
WebApiConfig.Register(GlobalConfiguration.Configuration);
FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
RouteConfig.RegisterRoutes(RouteTable.Routes);
BundleConfig.RegisterBundles(BundleTable.Bundles);
}
And CatalogAreaRegistration is something like this:
public class CatalogAreaRegistration : AreaRegistration
{
public override string AreaName
{
get
{
return "Catalog";
}
}
public override void RegisterArea(AreaRegistrationContext context)
{
context.MapRoute(
"Catalog_default",
"Catalog/{controller}/{action}/{id}",
new { action = "Index", id = UrlParameter.Optional }
);
}
}
The problem is when i debug, RouteCollection routes does not include rules that are defined in the area. I used routedebugger and saw that routes collection does not consists rules of "Catalog" area. It has only rules in the RouteConfig.
I have no idea what is the problem. Thanks in advance.
I think due to Visual Studio's caching, some of the dll's aren't compiled properly and this situation can happen. If you do, delete all temp files from following locations:
C:\Temp
C:\Users\%Username%\AppData\Local\Microsoft\VisualStudio
C:\Windows\Microsoft.NET\Framework\v4.0.30319\Temporary ASP.NET Files
C:\Windows\Microsoft.NET\Framework64\v4.0.30319\Temporary ASP.NET Files
Path\To\Your\Project\obj\Debug
Update :
AppData\Local\Temp\Temporary ASP.NET Files
Then restart the Visual Studio. This is how i resolved.
Just add the namespace of your controllers to the AreaRegistration:
public override void RegisterArea(AreaRegistrationContext context)
{
context.MapRoute(
"Admin_default",
"Admin/{controller}/{action}/{id}",
new { controller = "Home", action = "Index", id = UrlParameter.Optional },
**namespaces: new string[] { "Web.Admin.Controllers" }**
);
}
In my mvc application I have Admin area and have default controllers outside area. I want to define route in global.asax file so that both default and admin.
like if user type: {http://localhost/} -> open default route
if user type: {http://localhost/Admin/} -> open admin route
If someone has idea to handle this then please suggest.
Create an Admin area registration file. Such as:
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 { controller = "Admin", action = "Index", id = UrlParameter.Optional },
new[] { "Admin.Controllers" }
);
}
}
Then call this from your Global.asax
AreaRegistration.RegisterAllAreas();