简体   繁体   中英

ASP.NET MVC 5 passing data from home controller to layout via ViewBag

In my HomeController.cs I have some data, which I need to pass to my /Shared/_Layout.cshtml via ViewBag . But I have no idea, how can I do it.

This is my /Shared/_Layout.cshtml

@foreach (var item in ViewBag.Order)
{
    <li>@item.Name [ @item.Count ]</li>
}

And here is HomeController.cs

public ActionResult Index()
{
     ViewBag.Order = SELECT FROM DB -> ADD TO LIST
}

You don't have access to the Viewbag in the Layout View unfortunately. You could however use:

  • PartialView call to a method in a base controller Simply define a base controller that is a parent for all your controllers. This can also be handy for some error handling by the way. And in your layout use @Html.Partial("ViewName") to call your base controller.
  • Use Ajax call Use javascript in your layout view to execute a controller function that returns the data you need.
  • Use Session variables instead since session variables are accesable in layout views.

There are probably more answers too, but I believe these will probably be the most common solutions to your problem.

(If you need any help implementing one of these solutions please give me a sign and I'll explain it more deeply how to do it.)

A fairly common method of passing content to the layout, is to let all ViewModel classes implement a base class (or interface), which will then be the @model of your _Layout view.

Assuming you want to pass on some text MyText to all of your pages:

// My base view model class
public class ViewModelBase {
    public string MyText { get; set; }
}

// Some other view model
public class MyOtherViewModel : ViewModelBase {
    // other properties
}

// In the _Layout view, implement the base class
@model ViewModelBase
... 
@Html.DisplayFor(m => m.MyText)
...
@RenderBody()
...

This way, your _Layout view can work with all the properties of the ViewModelbase class, while whatever view is rendered after that still will have the properties of their child view model - here MyOtherViewModel - available.

Hope that helps!


On a side note, I would not recommend an extended use of ViewBags for passing data to your view in MVC, simply because it has a very low maintainability compared to other methods, due to it not being strongly typed. In my opition, ViewBags does not have any real benefits compared to - for instance - using viewmodels.

As an alternative, you can create a base controller inheriting from the controller and assigning the ViewBag variable to your list in the base controller constructor, like so

public class BaseController : Controller {
    public BaseController(){ 
        ViewBag.Order = SELECT FROM DB -> ADD TO LIST
    }
} 

Then in other controllers, inherit from the base controller like so

public class HomeController : BaseController {

}

This then allows you to assign the view bag for each controller request and the view bag variable will be available in the Layout View.

I myself have used this technique to show a list of car makes that is shown throughout the website.

As a suggestion though, I would implement some form of caching, to save constant calls to the back end.

However if you want to keep the functionality in the home controller you will need to restructure it so that it can be used via an Ajax call using jQuery/Javascript as @counterflux has suggested in their second point

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM