Setting Layout in ActionFilterAttribute.OnActionExecuted is problematic
Asked Answered
R

3

12

I'm trying to set the layout path in a custom ActionFilterAttribute I have written as follow:

public class LayoutInjecterAttribute : ActionFilterAttribute
{
    public override void OnActionExecuted(ActionExecutedContext filterContext)
    {
        base.OnActionExecuted(filterContext);
        var result = filterContext.Result as ViewResult;
        if (result != null)
        {
            result.MasterName = "~/Views/Layouts/Test.cshtml"
        }
    }
}

In here Test.cshtml is precompiled view (with the help of RazorGenerator) in a different project.

But it gives me the error:

The view 'Index' or its master was not found or no view engine supports the searched locations. The following locations were searched: ~/Views/Home/Index.cshtml ~/Views/Shared/Index.cshtml ~/Views/Home/Index.aspx ~/Views/Home/Index.ascx ~/Views/Shared/Index.aspx ~/Views/Shared/Index.ascx ~/Views/Layouts/Test.cshtml

and controller actually is simple:

[LayoutInjecter]
public class HomeController : Controller
{
    public ActionResult Index()
    {
       return View();
    }
}
Rhizo answered 20/11, 2015 at 15:31 Comment(5)
did you create the controller Layouts?Necklace
No, there isn't any controller named 'Layouts'Rhizo
Please add a new controller called layouts and then create a new action result called Test and return the view, and that should be workNecklace
is the Layouts folder available in all projects ?Kiloton
No. Only library project has that folder. I've tried to add an empty folder to the mvc project but nothing changed :(Rhizo
B
7

The error shows that LayoutInjecter is working fine. You said:

In here Test.cshtml is precompiled view in a different project.

But, Using razor views from a different (from outside the web project) is not supported out of the box. However there's a tool to precompile razor views and then you can put them in any DLL which called RazorGenerator. The compiler can't find the specified master layout file and shows this error.

For more information look at

Edit: How did the PrecompiledMvcViewEngine know which view to render?

PrecompiledMvcViewEngine still relies on the ASP.NET MVC Views folder convention, using relative file paths to locate the views. However, this is slightly misleading. The PrecompiledMvcViewEngine doesn’t look at physical files; it looks for the System.Web.WebPages.PageVirtualPathAttribute that the Razor Single File Generator adds to every view that it generates that includes the view’s relative file path.

Edit 2: I believe the guidance for your problem would be found in GitHub.

Bigotry answered 26/11, 2015 at 8:25 Comment(5)
I've actually did with RazorGenerator.Rhizo
@Rhizo I put an edit to my answer. Could you check if the generated files appear in the obj directory of your project and that the views get compiled in to your project assembly?Bigotry
I don't know why but, if the both projects are in same solution it works. But if they are in seperate solution, it doesn't work!Rhizo
@Rhizo See my Edit 2 please.Bigotry
All my views are marked as "Content". I don't think it helps me.Rhizo
B
4

It works. Make sure the layout path "~/Views/Layouts/Test.cshtml" is correct.

Also, make sure that "Test.cshtml" is a layout page, and not a view / partial view.

Beckwith answered 25/11, 2015 at 8:3 Comment(1)
Path is correct and Test.chstml is just a layout page.Rhizo
A
3

Change result.MasterName = "~/Views/Layouts/Test.cshtml" to result.MasterName ="~/Views/Shared/Test.cshtml". The Framework by convention looks in the ~/Views/Shared/ directory in your asp.net mvc solution for your layout pages. It appears to me you are dynamically or at runtime selecting a master page.

Alicyclic answered 28/11, 2015 at 0:48 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.