如何覆盖视图布局声明

时间:2013-07-29 18:41:23

标签: asp.net-mvc asp.net-mvc-3

在asp.net MVC 3中是否有一种方法可以覆盖来自控制器或动作过滤器的视图中的布局声明集?

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

我尝试覆盖OnResultExecuted或OnResultExecuting中的MasterName属性,如下面的代码片段,但无济于事。

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

4 个答案:

答案 0 :(得分:3)

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

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

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

Blog post where it was introduced by Scott Gu

答案 1 :(得分: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()

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

答案 2 :(得分:2)

使用ViewBag 当你需要更改布局时调用一个动作并将新布局(甚至为空)放在viewbag中。

@{
   Layout = ViewBag.layout;
}

并在行动中

if(something)
   ViewBag.layout = "~/Views/Shared/whatever.cshtml";
else
   ViewBag.layout = null;

答案 3 :(得分:0)

很抱歉,只需在我之前的帖子中添加一个关于此主题的参考,但看看这里,它可能会给出更广泛的观点(双关语):

Where and how is the _ViewStart.cshtml layout file linked?