Shared layouts not found with overridden View paths (Location Formats) in ASP.NET MVC
Asked Answered
L

2

6

I'm grouping my Views, Controllers and models. The structure is

~/Controllers
-- /_Shared
--  -- /Views
--  -- /Content
--  -- /Scripts
-- /Home
-- -- /Models
-- -- /Content
-- -- /Scripts
-- -- /Views
-- -- HomeController.cs
-- /Account
-- -- /Models
-- -- /Views
...

Views and partial views work, but layouts (master views) don't work. When I specify a layout in a .cshtml file like:

@{ Layout = "SimpleSharedLayout"; }

I get this error: The layout page "SimpleLayout" could not be found at the following path:

"~/Controllers/Account/Views/SimpleSharedLayout".

Asp.NET only searches the layout in the current controller's directory and doesn't look into the Shared folder *(which is at ~/Controllers/_Shared/Views)*

Although this works just fine.

@Html.Partial("SharedPartialView")

I have to specify layouts with full paths like

@{ Layout = "~/Controllers/_Shared/Views/SimpleSharedLayout.cshtml"; }

Which is not a hard thing to do but I'm crazy about not being able to get it working.

Using IIS Express, VS 2012, .NET 4.5

Do you have an idea about what I'm missing?

My View Engine:

public class AreaViewEngine : RazorViewEngine
{
    public AreaViewEngine()
    {
        AreaViewLocationFormats = new[] {
                         "~/Controllers/{1}/Views/{0}.cshtml",
                         "~/Controllers/_Shared/Views/{0}.cshtml"};

        ViewLocationFormats = AreaViewLocationFormats;

        AreaMasterLocationFormats = new[] { "~/Controllers/_Shared/Views/{0}.cshtml" };

        MasterLocationFormats = AreaMasterLocationFormats;

        AreaPartialViewLocationFormats = new[] { "~/Controllers/_Shared/Views/{0}.cshtml",
                         "~/Controllers/{1}/Views/{0}.cshtml"};

        PartialViewLocationFormats = AreaPartialViewLocationFormats;
    }
 }
Latea answered 1/4, 2013 at 23:26 Comment(0)
T
2

IMHO, you are fighting the framework's conventions. It would be my recommendation to utilize the framework in the way that it was intended with these kinds of scenarios by creating Areas.

I know it's probably not the answer you want, but I feel like what you have described is Areas to a T.

Teodor answered 4/4, 2013 at 22:6 Comment(3)
Yeah but when I open a controller I want to see all related files to that controller. They are views, custom css and js files and models. Why they are in separate folders anyway? When I'm working with a controller I also work with related model and related view at the same time. And yes, Areas is not the feature I'm looking for. What I created is between areas and classical approach.Latea
You will be assimilated. Resistance is futile. :) In all seriousness, yes you can make the convention work the way you want, but at some point you have to question whether the effort is worth all that. Far be it from me to crush your frontier spirit, but in your place, I would put my time into Areas and concentrate on making the project the best that it can be. Good luck, my friend.Outshine
I totally agree with you, that's for sure. I already gave up :) Even Resharper doesn't popup some views and makes me crazy. I think i gotta revert to the original structure...Latea
M
0

Try overloading the ViewEngine and overwriting the AreaMasterLocationFormats and MasterLocationFormats. Check this other amazing answer, it's maybe what you are looking for.

How to set a Default Route (To an Area) in MVC

Ignore the title, it's not really about routes, but where and how the viewEngine searches for files.

Mansuetude answered 13/6, 2013 at 21:44 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.