resolve correct _layout from an Area

Aug 29, 2013 at 12:12 PM
Edited Aug 29, 2013 at 12:31 PM
I hope this makes sense.

I am trying to build modular components using RazorGenerator.
The problem I am having is when I load a view from the PreCompiledView library into an Area. The loaded view uses the _layout from the host website root rather than the _layout in for the Area.
  • Web
    --- Areas
    ----- Admin
    ------- Controllers
    --------- HomeController.cs (Index action)
    ------- Views
    --------- Home
    ----------- Index.cshtml
    --- Shared Views
    ----- _layout
--- Controllers
----- HomeController.cs (Index action)
--- Views
----- Home
------- Index.cshtml
--- Shared Views
----- _layout (this gets used)

and in my PreCompiledView Library
  • Web
    --- Controllers
    ----- ContactsController.cs (Index action)
    --- Views
    ----- Contacts (Load this view into the Admin Area)
How can I resolve the _layout for the Area rather than using the website root _layout?
Aug 29, 2013 at 1:43 PM
You might need to use the "PreemptPhysicalFiles" flag as described here
Aug 29, 2013 at 2:23 PM
Hi Pranavkm
I have tried this approach already and it did not work.
by setting PreemptPhysicalFiles=true the _layout from the PreCompiledView Library is used. Again this is not what I need.
Aug 29, 2013 at 2:53 PM
Making sure this works before I look into it - if you drop a view in the area folder of your Mvc application, does it pick up the correct _Layout file?
Aug 29, 2013 at 2:59 PM
yes, I have a 'bare' landing page on the MVC host site and a themed layout on the Admin area. other pages on the Admin area pick up the correct _layout. But the view 'imported' from the PreCompiledView lib resolves the _layout from the 'bare' website;

Thanks for you help
Sep 3, 2013 at 3:42 AM
I think the problem might be how the path to the layout is specified. The _Layout path for a regular vin an application created from a template is "~/Views/Shared/_Layout.cshtml". From this it follows that the value for _Layout needs to be an absolute virtual path. I tried creating an app with a layout similar to yours (no pun intended :)) and I was able to get it to pick up the right one by setting Layout to "~/Areas/Shared/_Layout.cshtml".

Non-precompiled areas also worked in a similar way for me so I think this is the right behavior. Let me know if you think otherwise.
Sep 3, 2013 at 7:18 AM
I don't really understand what you are trying to explain.

Let me see is I can describe the problem more clearly.
I am trying to build components using precompiled views.

1) I have a standard web application which contains an Area called "Admin"
2) I have a precompiledview which contains a view/controller/model called MyProfile
2) The Area layout implements a link <a href='@Url.Action("Index", "MyProfile", new { area = "Admin" }, null)'>

My problem is that when the "MyProfile" action is called, the _layout from the website root is resolved rather than the "Admin" area _layout.
I'm not sure if your answer was saying that I need to resolve the area layout in the precompiled view! If so then that is not suitable for my solution as I want to make the precompiledviews loosely coupled and not dependent on the host application.
Sep 3, 2013 at 5:51 PM
Sorry, I guess I'm still having trouble figuring out your scenario. Do you think you could get us a repro app with this issue? There's an app we we've been using for debugging scenarios - - a pull request to it would work great.
Sep 3, 2013 at 8:55 PM
Edited Sep 3, 2013 at 8:55 PM
Sorry I don't have much experience with Github and didn't understand what a Pull would do. I didn't want to stomp on your code so I created my own repo with a test solution I have put together that demonstrates my problem.

Website Home -> Click on "Admin Area"
On Admin Area - > Click PrecompiledView

My repo is here
Sep 8, 2013 at 8:09 PM
Sorry it took me this long to get back to you. I tweaked your solution - - can you have a look?
Sep 12, 2013 at 9:26 AM
Thanks Pranavkm
Although I managed to accidentally merge the Repos (I told you I don't know how it works :))
I can see what you have suggested, unfortunately this does not fit with what I want to do.

I want to achieve "modular components" (like a widget or webpart) that can be included anywhere within the app and that do not have any cognisance of where they have been plugged in.

Your tweak imposes the Area naming convention onto the 'PreCompiledView' component.

Am I asking for something which is not feasible?
Sep 16, 2013 at 4:11 PM
I don't think that's quite doable. Since both the Layout pages end up having the same virtual path, there's no way to discern which one you need with the way Mvc currently looks up Layout files.