2

我有一个组织成多个区域的 ASP.NET MVC 4 站点。每个区域都有一个Views/Shared/_Layout.cshtml引用公共共享布局的视图。在通用布局中,我有一个包含项目列表的侧边栏。我希望能够拥有所有_Layout.cshtml视图都可以访问的共享项目列表,以便聚合一组链接。

Area1/Views/Shared/_Layout.cshtml:

@{
   SidebarItems.Add("Area1 Item");
   Layout = "~/Views/Shared/_Layout.cshtml";
}

视图/共享/_Layout.cshtml:

@{
   SidebarItems.Add("Common Item");
}
<ul>
@foreach (var item in SidebarItems)
{
   <li>@item</li>    @* List should contain two items: "Area1 Item", and "Common Item" *@
}
</ul>

我尝试了两种方法:

  1. WebViewPage<T>为从公共自定义类继承的每个区域创建一个自定义WebViewPage<T>类,并使SidebarItems集合成为公共基类的属性。这不起作用,因为 RazorWebPageView在布局之间移动时似乎分配了一个新的。

  2. 创建一个带有静态集合的静态类,每个都_Layout调用该静态集合来添加项目。这成功地累积了列表项,但是,由于它是一个静态类,它的生命周期与应用程序域相关联,这意味着侧边栏会累积来自多个请求访问的每个区域的项,而不是每个请求的列表。

我正在考虑使用该HttpRequest.Items属性,但这似乎太短暂了——项目列表不会因请求而改变,并且完全由显示的区域视图决定。

另一种选择是将列表的呈现推送到section每个区域中呈现的_Layout. 这不太理想,因为我希望在呈现列表的代码中有一个点,但这是可行的。

建议?

4

1 回答 1

3

您可以尝试使用 ViewBag。

我通过添加一个名为ItemsViewBag 的属性进行了快速测试。这将从每个区域(通过添加自己的项目)和主布局中通过添加公共项目来填充。然后它将用于呈现主布局中的项目列表。

Area1\Views\Shared_Layout.cshtml

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

    if (ViewBag.Items == null){ViewBag.Items = new List<String>();}
    ViewBag.Items.Add("Area1 item");
}

<h2>Area1 Layout</h2>

@RenderBody()

Views\Shared_Layout.cshtml(部分)

@{
    if (ViewBag.Items == null){ViewBag.Items = new List<String>();}
    ViewBag.Items.Add("Common Item");
}
<ul>
@foreach (var item in ViewBag.Items)
{
    <li>@item</li>    @* List should contain two items: "Area1 Item", and "Common Item" *@
}
</ul>

我不太喜欢该代码的外观,因为它重复了很多次并传播了 ViewBag.Items 的使用。通过使用 Html 帮助器将项目添加到列表并呈现列表,它可能会更干净。例如,您可以创建以下 2 个 Html 助手:

public static class HtmlHelpers
{
    public static void AddCommonListItems(this HtmlHelper helper, params string[] values)
    {
        if(helper.ViewContext.ViewBag.Items == null) helper.ViewContext.ViewBag.Items=new List<String>();
        helper.ViewContext.ViewBag.Items.AddRange(values);
    }

    public static MvcHtmlString CommonList(this HtmlHelper helper)
    {
        if (helper.ViewContext.ViewBag.Items == null)
            return new MvcHtmlString(new TagBuilder("ul").ToString());

        var itemsList = new TagBuilder("ul");
        foreach (var item in helper.ViewContext.ViewBag.Items)
        {
            var listItem = new TagBuilder("li");
            listItem.SetInnerText(item);
            itemsList.InnerHtml += listItem.ToString();
        }
        return new MvcHtmlString(itemsList.ToString());

    }
}

然后您的视图会看起来更清晰,因为它们只会使用这些帮助程序并避免重复代码:

Area1\Views\Shared_Layout.cshtml(使用新的 Html 助手)

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

    Html.AddCommonListItems("Area1 item", "Area1 item 2");
}

<h2>Area1 Layout</h2>

@RenderBody()

Views\Shared_Layout.cshtml(其中的一部分,使用新的 Html 助手)

@{Html.AddCommonListItems("Common Item");}
@Html.CommonList()
于 2013-05-21T20:50:01.567 回答