如何将局部视图传递给布局

时间:2017-03-07 21:37:17

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

这是我对将部分视图传递给布局标题的方法的完整性检查。

在我的布局中,我有一个我想为每个页面显示的导航按钮的位置。

使用该布局的视图模型,我可以将一串数据传递给布局并将其显示在该位置,没问题。

我目前正在构建我想要在局部视图中显示的导航,然后将其渲染为字符串并通过布局视图模型将其传递到布局中,一切正常。

这是将局部视图传递给布局的常用方法还是有更好的方法?

正如我所说的,这工作得非常好,但是渲染html通过一个字符串似乎有些迟钝。能够本地传递局部视图并使其在布局中呈现而不是传递HTML(如果可能的话)将是很好的。

感谢您提出的建议。

厄尔

1 个答案:

答案 0 :(得分:0)

您应该传递部分视图的名称(或实例),并让它呈现内联(因此没有中间字符串分配)。

您应该使用ViewData进行单向(控制器到视图)数据交换而不是ViewModel(在我看来应该用于双向数据)。

像这样:

View.cshtml

@model SomeViewModel
@{
    Layout = "Layout.cshtml";

    if( userIsAdmin ) {
        this.ViewData["NavigationPartialName"] = "AdminLinks";
    }
    else {
        this.ViewData["NavigationPartialName"] = "NormalLinks";
    }
}

Layout.cshtml:

<nav>
    @{ Html.RenderPartial( this.ViewData["NavigationPartialName"] ); }
</nav>

(请注意,Html.RenderPartial通常优于Html.Partial,因为它直接写入父输出流或缓冲区,而Html.Partial只返回MvcHtmlString,效率很低,除非你真的需要一个中间字符串。因为RenderPartial是一个void方法,你需要将其包含在@{ }中,而不是需要返回值的更简洁的@()。< / p>

但是这可以简化,部分显示逻辑可以完全存在于布局文件中:

@{
    Boolean userIsAdmin = this.ViewData["UserIsAdmin"];
}

<nav>
    @{ Html.RenderPartial( userIsAdmin ? "AdminLinks" : "NormalLinks" ); }
</nav>

您可以在控制器中设置this.ViewData["UserIsAdmin"]

class BaseController : Controller {

    protected override void OnResultExecuting(ResultExecutingContext filterContext) {

        this.ViewData["UserIsAdmin"] = this.User.IsInRole("Administrator");
    }
}

如果您不喜欢为ViewData使用字典,也可以使用强类型的ViewData子类,也可以将"UserIsAdmin"键字符串存储为全局const。