Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Custom Folder Structure in ASP.NET MVC 5

I'm trying to determine if it is possible (or practical) to implement Uncle Bob's Screaming Architecture in ASP.NET MVC 5 rather than using the default folder structure.

Here's a link to a description of the Screaming Architecture: http://blog.8thlight.com/uncle-bob/2011/09/30/Screaming-Architecture.html

A hypothetical folder structure would look something like this:

Root

  • Customers
    • Controllers
      • CustomerController.cs
    • Models
      • Customer.cs
    • Views
      • Index.cshtml
      • Details.cshtml
      • Update.cshtml
  • Employees
    • Controllers
      • EmployeesController.cs
    • Models
      • Employee.cs
    • Views
      • Index.cshtml
      • Details.cshtml
      • Update.cshtml
  • Shared
    • Views
      • _Layout.cshtml
      • Error.cshtml
  • _ViewStart.cshtml
  • Web.config

The corresponding URL routes would look like this:

  • http://www.example.com/customers/ => Customer Index
  • http://www.example.com/customers/details/1 => Customer Details
  • http://www.example.com/customers/update/1 => Customer Update
  • http://www.example.com/employees/ => Employee Index
  • http://www.example.com/employees/details/1 => Employee Details
  • http://www.example.com/employees/update/1 => Employee Update

I've created a custom RazorViewEngine and added the appropriate view location formats (e.g. "~/{1}/Views/{0}.cshtml") and partial view location formats (e.g. "~/Shared/Views/{0}.cshtml"). I've also moved the shared _ViewStart.cshtml to the root and merged the Views/Shared folder's web.config with the root-level web.config to avoid having to duplicate these two files in all of the View folders.

Everything works great, however, if I try navigating to an index page (e.g. http://www.example.com/employees/) I get a 403.14 Error (Forbidden). All other routes (including http://www.example.com/employees/index) work just fine.

My guess is that IIS is explicitly blocking the route to the controller's index method because the URL coincides with a folder in the filesystem and directory browsing is disabled by default. If I enable directory browsing, however, it actually takes me to the actual directory listing rather than routing to the controller's index method.

I can move the Customers and Employees folders into a subfolder (i.e. move them out of the root) and everything works fine, but I'd like to try to keep these folders at the top level (per the Screaming Architecture guidelines).

Does anyone have a solution for this issue?

Please note that MVC Areas is not the solution I'm looking for as it does not allow for the folder structure described above (i.e. top-level folders named after high-level use cases and views contained directly within the Views folder rather than in a subfolder).

like image 272
Matthew Renze Avatar asked Apr 14 '15 20:04

Matthew Renze


1 Answers

I'm betting you are right about IIS then. If you have two paths mapped to the same resource, the physical path is checked first on the IIS side.

I was digging around the routes configuration and found the property RouteExistingFiles on RouteCollection and think this could work.

I set the value to true and tested locally with an empty folder in the project, a route redirecting to Home/Index, and navigating to localhost:xxx/MyFolder. It worked correctly.

So then all you should need to do is set this property to true for it to choose Asp.net routes first instead of physical routes.

like image 117
James Sampica Avatar answered Sep 25 '22 17:09

James Sampica