简体   繁体   English

ASP.NET MVC 5通过ViewBag将数据从家庭控制器传递到布局

[英]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 . 在我HomeController.cs我有一些数据,我需要传递给我的/Shared/_Layout.cshtml通过ViewBag But I have no idea, how can I do it. 但是我不知道该怎么办。

This is my /Shared/_Layout.cshtml 这是我的/Shared/_Layout.cshtml

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

And here is HomeController.cs 这是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. 不幸的是,您无权访问布局视图中的Viewbag。 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. 对基本控制器中的方法的PartialView调用只需定义一个基本控制器即可,它是所有控制器的父级。 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. 在您的布局中,使用@Html.Partial("ViewName")调用您的基本控制器。
  • Use Ajax call Use javascript in your layout view to execute a controller function that returns the data you need. 使用Ajax调用在布局视图中使用javascript来执行返回所需数据的控制器功能。
  • 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. 传递内容的布局的一个相当普遍的方法,是让所有视图模型类实现一个基类 (或接口),其然后将是您_layout视图的@model。

Assuming you want to pass on some text MyText to all of your pages: 假设您要将一些文本MyText传递给所有页面:

// 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. 这样,您的_Layout视图可以使用ViewModelbase类的所有属性,而此后呈现的任何视图仍将具有其子视图模型(此处为MyOtherViewModel)的属性。

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. 附带说明一下,我不建议您广泛使用ViewBags来将数据传递到MVC中的视图中,这仅仅是因为与其他方法相比,它的可维护性很低,因为它的类型不严格。 In my opition, ViewBags does not have any real benefits compared to - for instance - using viewmodels. 根据我的选择,与使用Viewmodels相比,ViewBags没有任何真正的好处。

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 或者,您可以创建从控制器继承的基本控制器,并将ViewBag变量分配给基本控制器构造函数中的列表,如下所示

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 但是,如果要将功能保留在家庭控制器中,则需要对其进行重组,以便可以使用jQuery / Javascript通过Ajax调用来使用它,如@counterflux在第二点中所建议的那样。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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