Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Setting Layout in ActionFilterAttribute.OnActionExecuted is problematic

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();
    }
}
like image 938
Kaan Avatar asked Nov 20 '15 15:11

Kaan


3 Answers

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.

like image 72
Amirhossein Mehrvarzi Avatar answered Oct 10 '22 17:10

Amirhossein Mehrvarzi


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.

like image 3
Julius Depulla Avatar answered Oct 10 '22 17:10

Julius Depulla


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.

like image 4
Catalin Avatar answered Oct 10 '22 16:10

Catalin