4

In asp.net MVC 3 is there a way to override the Layout declaration set in a view from a controller or action filter?

@{
    Layout = "~/Views/Shared/_Layout.cshtml";
}

I have tried overriding the MasterName property in the OnResultExecuted or the OnResultExecuting like the following code snippet, to no avail.

public override void OnResultExecuting(ResultExecutingContext filterContext)
{
    var view = filterContext.Result as ViewResult;
    view.MasterName = null;
}
4

4 回答 4

3

另一个可以控制布局的地方是_ViewStart.cshtml.

在这里,您可以执行所需的逻辑并以编程方式指定要使用的布局。这允许您将逻辑仅放置在一个位置并将其置于视图之外。

@{
    if(myBusinessRule)
    {
       Layout = "~/Views/Shared/_Layout.cshtml";
    }
    else
    {
       Layout = "~/Views/Shared/_SecondaryLayout.cshtml";
    }
}

由 Scott Gu 介绍的博客文章

于 2013-07-29T19:32:52.067 回答
3

您可以创建一个操作过滤器来覆盖布局文件,但如果要删除它,则必须创建一个空的布局文件,而不是将 Master 属性分配为 null。像这样:

public class OverrideLayoutFilter : ActionFilterAttribute
{
    public override void OnResultExecuting(ResultExecutingContext filterContext)
    {
        var view = filterContext.Result as ViewResult;
        view.MasterName = "_LayoutEmpty";
        base.OnResultExecuting(filterContext);
    }
}

控制器:

public class HomeController : Controller
{
    [OverrideLayoutFilter]
    public ActionResult Index()
    {
        return View();
    }
}

现在您的新布局文件需要放在 SharedFolder 中,您只需将 RenderBody 函数放在里面

_LayoutEmpty.cshtml

@RenderBody()

注意:如果您在要覆盖布局的视图中定义了部分,您还必须使用空内容定义这些部分。

于 2013-07-29T19:45:20.833 回答
2

当您需要更改布局调用操作并将新布局(甚至为 null)放入 viewbag 时,请使用 ViewBag。

@{
   Layout = ViewBag.layout;
}

在行动内部

if(something)
   ViewBag.layout = "~/Views/Shared/whatever.cshtml";
else
   ViewBag.layout = null;
于 2013-07-29T18:56:19.563 回答
1

很抱歉简单地在我之前关于这个主题的一篇文章中添加一个参考,但是看看这里,它可能会给出关于这个主题的更广泛的观点(双关语):

_ViewStart.cshtml 布局文件在哪里以及如何链接?

于 2013-07-29T20:08:06.623 回答