Display Dynamic data on the ASP.NET MVC 4 layout master page
Asp.net mvc4 is an evolution of web development. Asp.net mvc4 offer lot of facilities to developers to build state of the art dynamic websites to cater any platform. In this article shows how to display dynamic data or else data from database into Layout master pages.
What are layout master pages?
In simple terms layout master pages are the master pages of your ASP.NET MVC website. Master pages are used to display common data and sections for all the pages. MVC view engine finds this layout master pages using the viewstart guide lines. It gives the path to locate the Layout master. You can locate layout pages inside the ASP.NET MVC solution views->shared folder. One problem with _Layout.csHtml it is not associated with a controller. Therefor you need special ways to display dynamic data on the layout master.
The Scenario
Now assume you want to display dynamic data from your database into _Layout.csHtml file. A typical example would be you want to display available cities on the header section of _Layout master page as a dropdownlist.
To display dynamic data in a razor view there are many ways, but all of them are not going to be strait forward. Since the _Layout master view is not bound to a controller, so you cannot display dynamic data directly on to _Layout page.
How to display dynamic data?
One method will be using a partial view to display dynamic data. You can create a common controller and create an action method to fetch available cities from the database and display as partial view.
public ActionResult CityDropList() { //Linq query to get city details from the DB var cityList = (from p in entity.Citiesmasters where p.enabled==true select new { p.ID, p.city }); //Create selectlistitem list List<SelectListItem> items = new List<SelectListItem>(); SelectListItem s = null; //add the empty selection s = new SelectListItem(); s.Value = "----select city----"; s.Text = ""; items.Add(s); foreach (var t in cityList) { s = new SelectListItem(); s.Text = t.ID.ToString(); s.Value = t.city.ToString(); items.Add(s); } //bind seleclistitems list to to viewBag ViewData["CityList"] = items; //returning the partial view return PartialView(); }
First you need to create a selectionItem list and assign it to viewbag as shown in the above code. Once action method is ready you can compile the solution before generate the view. Then by right clicking on the PartialView() method you can create a partial view. Your view will look a very simple one. Since it will going to contain only one dropdown it would look as follows;
@Html.DropDownList("selectCity", new SelectList(ViewBag.CityList, "Text", "Value"),new{@class="selectcity"})
To display the drop down list you can use the viewbag. As in the action method we store CityList as a SelectionItem list in the viewData, In the Razor view the same list can be retrieved as a property of the viewbag shown above.
One important point to remember would be, the action method must return a partialView. If not, when you call this action method from the master page(_Layout) it will create an infinite loop.
There are many ways available in the Razor view engine to render this data on the _Layout view. They are as follows;
- @html.RenderAction()
- @html.RenderPartial()
- @html.Partial()
- @html.Action()*
In this example I will use the _Layout master page header section to display the dropdownlist. You can select either of methods shown above to render the partial view on the _Layout. Let us discuss each method and there drawbacks.
Assume you have selected html helper RenderAction method. In this case the method will render the partial view and display dropdown only on the home page. When you try to navigate to other pages, the viewbage is getting null and throws an exception. The reason for that is, RenderAction method is not calling the get city list action method each time you load the other pages.
Assume you select the html helper RenderPartial() method. In this case also the drop down will display only on the home page but not in the other pages. Same reason action method is not getting called with the other page calls.
If you choose the html helper method Partial() you will notice that your partial view should be located inside views->shared folder. By default Razor view engine direct Partial() method to search the shared folder to locate the partial view. In this scenario also the results are being displayed only on the home page and generate exception on the other pages.
Finally if you use html helper Action() method you can notice each time you navigate to different pages which inherit the _Layout master page it trigger the action method and fetch data from the database. Out of all four html helper methods the only method that trigger action method each time is @html.Action() method. Using this html helper method we can simply display dynamic data from the database.
Finally you can display the partial view as follows in the _Layout page as follows;
<section id="selectcity"> <ul> <li>Select a City</li> <li> @Html.Action("CityDropList", "Partial") </li> </ul> </section>
Above code will render the dropdown list on the _layout master page.
5 Comments
Join the discussion and tell us your opinion.
Sometimes we need to generate menu form database according to our requirements. The following URL
http://cybarlab.blogspot.com/2013/04/generate-dynamic-menu-in-aspnet.html
will help you to generate menu dynamically in ASP.NET. You can apply your customize CSS as you like to give nice outlook of the menu.
Hope it will help you
It’s great article and very helpful, but after reading it I’ve some questions.
1. How to refresh current page on dropdown change, I mean take a look on such situation:
– I’ve dropdown at layout page
– I’m at ‘About’ page and on change ddl want to refresh data on ‘Abut’
– but when I’m at ‘Home’ page I want to refresh data on ‘Home’
2. How to store selected value through different pages, because right now on each page dropdownlist set first value as selected. (maybe by System.Web.HttpContext.Current.Session ?)
I know it’s messed 🙂
Regards,
Marcin
Hi Marcin,
Sorry for the delay to reply.
For the first question answer is; Every time you change the selection of the dropdown list, in ASP.NET MVC it fires the action result method of the partial controller. In that method you can trace the request path and rout it back to the original rout. In this scenario the drop down list act as the main cities for the entire application. When the city change all the results get effected.
Second question is a good one. Yes it was not included in the article. Yes you can use the session to keep track of the state of the current selection. In my case I use cookie. Each time the page refresh in side the partial class I check for the state of the current selection if it exist mark that list item as selected.
Hope this helps you..
Hi, great article, gave me some ideas, thx! When I think of dynamic content though I think of a value displayed on a form that is not pre-determined. So, I had this label field in the header section of an old web form master page that allowed me to display a value to it from the code behind the current aspx page.
So for example, if I queried my inventory for widgets purchased from Jan 1 – Dec 31 this year, the message in the header would say ‘Widgets purchased between Jan 1 and Dec 31, 2016’. And the header label would dynamically change with the selected product and given date ranges.
Do you think there is a way to have a message dynamically populate in the header of a layout page based on the view? I am finding MVC quite challenging but I don’t want to give up on it, I want to find a way to achieve the same results in MVC as in my Web Forms app.
Thanks!
Hi Joanne,
There are few ways to do this. If you are keen on using MVC to solve this? Solution is use a helper controller. This is how you should be coding it
public class LayoutController : BaseController
{
[ChildActionOnly]
public ActionResult LabelName()
{
return new ContentResult {Content = "label name goes here"};
}
}
Above code uses the LayoutController and an action result that is going to use for child actions only. once you create above code you can use it in the view or layout as follows;
@{Html.Action("LabelName", "Layout")}
If not you can think of a solution with Angularjs
Hope this would help
Thanks