Search code examples
c#asp.net-mvcurl-routingasp.net-mvc-routingasp.net-mvc-areas

Route to Subdirectory in an Area


I have created an area as such: Admin/

I am attempting to create a subdirectory within that area as: Admin/Permissions/ByGroup/ with functions such as Admin/Permissions/ByGroup/Edit/1, etc. This is because I will have additional ways to view and edit permissions such as ByUser, ByActivity, etc.

However, I'm having an issue routing correctly to the ByGroupController and its views. Admin/ and Admin/Permissions/ (fires out of the PermissionsController) both work fine.

Exception when navigating to Admin/Permissions/ByGroup/:

Server Error in '/' Application.

The view 'Index' or its master was not found or no view engine supports the searched locations. The following locations were searched:
~/Areas/Admin/Views/ByGroup/Index.aspx
~/Areas/Admin/Views/ByGroup/Index.ascx
~/Areas/Admin/Views/Shared/Index.aspx
~/Areas/Admin/Views/Shared/Index.ascx
~/Views/ByGroup/Index.aspx
~/Views/ByGroup/Index.ascx
~/Views/Shared/Index.aspx
~/Views/Shared/Index.ascx
~/Areas/Admin/Views/ByGroup/Index.cshtml
~/Areas/Admin/Views/ByGroup/Index.vbhtml
~/Areas/Admin/Views/Shared/Index.cshtml
~/Areas/Admin/Views/Shared/Index.vbhtml
~/Views/ByGroup/Index.cshtml
~/Views/ByGroup/Index.vbhtml
~/Views/Shared/Index.cshtml
~/Views/Shared/Index.vbhtml

Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code. 

My folder structure is this for the areas:

enter image description here

AdminAreaRegistration.cs

using System.Web.Mvc;

namespace MyMVCSite.Areas.Admin
{
    public class AdminAreaRegistration : AreaRegistration
    {
        public override string AreaName
        {
            get
            {
                return "Admin";
            }
        }

        public override void RegisterArea(AreaRegistrationContext context)
        {
            context.MapRoute(
                "ByGroup_default",
                "Admin/Permissions/ByGroup/{controller}/{action}/{id}",
                new { controller = "ByGroup", action = "Index", id = UrlParameter.Optional },
                namespaces: new[] { "MyMVCSite.Areas.Admin.Controllers" }
                );

            context.MapRoute(
                    "Permissions_default",
                    "Admin/Permissions/{controller}/{action}/{id}",
                    new { controller = "Permissions", action = "Index", id = UrlParameter.Optional },
                    namespaces: new[] { "MyMVCSite.Areas.Admin.Controllers" }
                    );

            context.MapRoute(
                 "Admin_default",
                 "Admin/{controller}/{action}/{id}",
                 new { controller = "Home", action = "Index", id = UrlParameter.Optional },
                 namespaces: new[] { "MyMVCSite.Areas.Admin.Controllers" }
            );




        }
    }
}

ByGroupController.cs

namespace MyMVCSite.Areas.Admin.Controllers
{
    public class ByGroupController : Controller
    {
        // GET: Admin/ByGroup
        public ActionResult Index()
        {
            return View();
        }

        // GET: Admin/ByGroup
        public ActionResult Edit()
        {
            return View();
        }
    }
}

I haven't really used MVC for anything other than simple websites and not one with so many levels of views. What am I going about this wrong and is there a better way to organize areas with subdirectories of views? I haven't really had to go about custom routing, so my AdminAreaRegistration.cs may also be incorrect.

I appreciate any help or guidance.


Solution

  • By default routing is just an abstraction - that is, your URLs have absolutely nothing to do with the physical location of your controller. You can use routing to make the URLs any way you want while putting your controllers anywhere you want.

    Views on the other hand take some extra work to put into different directories that don't follow the conventions. You can do it by changing the view engine - see Can I specify a custom location to "search for views" in ASP.NET MVC?.

    There is a 3rd party package that gets you part of the way there - MvcCodeRouting will automatically generate routes based on the folders you put your controllers in. But, it is still up to you to modify the view engine to search for views as these are completely separate concerns.