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:

  1. create custom webviewpage<t> class each area inherits common custom webviewpage<t> class , make sidebaritems collection property of common base class. not work appears razor allocates new webpageview when moving between layouts.

  2. 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

Popular posts from this blog

blackberry 10 - how to add multiple markers on the google map just by url? -

php - guestbook returning database data to flash -

delphi - Dynamic file type icon -