Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to load a Model into _Layout.cshtml and share it among various Views?

I have an MVC4 project that deals with "Courses". Many pages throughout the app need to deal with a list of Courses - user profiles need to pull up the list, the Index view for /Courses needs to pull the list, etc.

Since this data is pretty much always required, I'd like to load it as part of the initial request, so I only have to query the DB one time.

I imagine a scenario where the data gets placed in Layout.cshtml, and then other views can access the Model data as needed, though I don't see a clear way of achieving this. I think I can break the problem into two pieces:

  1. Get the data loaded into Layout.cshtml
  2. Access this data from other views

I'm a bit stuck on both - how can I make this work?

like image 658
RobVious Avatar asked Sep 18 '13 18:09

RobVious


2 Answers

You should use Cache or OutputCache, put this list into a Partial View, and then render it everywhere you need:

1) Create an Action to pupulate the Partial View. This view will be cached for max duration time, then any access will not generate any overhead:

[NonAction]
[OutputCache(Duration = int.MaxValue, VaryByParam = "none")]
public ActionResult GetCourses()
{
  List<Course> courses = new List<Course>();

  /*Read DB here and populate the list*/

  return PartialView("_Courses", courses);
}

2) Using Chache populating the Partial View in the same way:

[NonAction]
public ActionResult GetCourses()
{
  List<Course> courses = new List<Course>();

  if (this.HttpContext.Cache["courses"] == null)
  {
    /*Read DB here and populate the list*/

    this.HttpContext.Cache["courses"] = courses;
  }
  else
  {
    courses = (List<Course>)this.HttpContext.Cache["courses"];
  }

  return PartialView("_Courses", courses);
}

3) Render this View by Html.Action or Html.RenderAction:

@Html.Action("GetCourses", "ControllerName")

or

@{ Html.RenderAction("GetCourses", "ControllerName"); }

More information about caching: Improving Performance with Output Caching

like image 88
Fals Avatar answered Oct 01 '22 20:10

Fals


I have two answers, because I'm not sure I understand your desire.

1) Create static helper method:

public static class Helper
{
  public static List<Course> GetCourses()
   {
    return db.Courses.ToList();
    }

}

Then you may call it everythere in View or Layout:

@Helper.GetCourses()

2) I prefere not to render business logic in Views or Layout. I would create BaseController. Get List<Course> in this controller. Other controllers should inherit from BaseController. So in any controller's method you may have the same instance of List<Course>.

like image 24
Andrey Gubal Avatar answered Oct 01 '22 21:10

Andrey Gubal