asp.net mvc - Add data to a common _Layout.cshtml from an MVC area's _Layout.cshtml -
i have asp.net mvc 4 site organized multiple areas. each area has views/shared/_layout.cshtml
view references common shared layout. in common layout, have sidebar contains list of items. ability have shared list of items can accessed of _layout.cshtml
views in order aggregate set of links.
area1/views/shared/_layout.cshtml:
@{ sidebaritems.add("area1 item"); layout = "~/views/shared/_layout.cshtml"; }
views/shared/_layout.cshtml:
@{ sidebaritems.add("common item"); } <ul> @foreach (var item in sidebaritems) { <li>@item</li> @* list should contain 2 items: "area1 item", , "common item" *@ } </ul>
i have tried 2 approaches:
create custom
webviewpage<t>
class each area inherits common customwebviewpage<t>
class , makesidebaritems
collection property of common base class. not work appears razor allocates newwebpageview
when moving between layouts.create static class static collection each
_layout
calls add items. accumulates list items, but, since it's static class, lifetime tied application domain, means sidebar accumulates items every area visited across multiple requests, rather being per-request list.
i considering using httprequest.items
property, seems short-lived -- list of items not change across requests , determined area's view displayed.
the other alternative push rendering of list section
rendered in each area's _layout
. less ideal, have single point in code renders list, doable.
suggestions?
you can try using viewbag it.
i have done quick test adding property named items
viewbag. populated every area (by adding own items) , main layout adding common items. used render list of items main layout.
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 (part of it)
@{ 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 2 items: "area1 item", , "common item" *@ } </ul>
i don't how code looks, repeating quite bit , spreading usage of viewbag.items. cleaner using html helpers adding items list , rendering list. example, create following 2 html helpers:
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()); } }
and views cleaner, use helpers , avoid repeating code:
area1\views\shared_layout.cshtml (using new html helpers)
@{ viewbag.title = "_layout"; layout = "~/views/shared/_layout.cshtml"; html.addcommonlistitems("area1 item", "area1 item 2"); } <h2>area1 layout</h2> @renderbody()
views\shared_layout.cshtml (part of it, using new html helpers)
@{html.addcommonlistitems("common item");} @html.commonlist()
Comments
Post a Comment