我已经创建了ASP.NET核心应用程序,现在我试图在_LoginPartial中使用ViewBag。我创建了基本控制器:
public class BaseController : Controller
{
public ApplicationDbContext _db;
public BaseController(ApplicationDbContext db)
{
_db = db;
ViewData["MyKey"] = _db.MyTable.ToList();
}
}我所有的控制器都来自这个BaseController。
但是当我在ViewData中看到_LoginPartial.cshtml时,我只能看到它包含默认的Key=Title,Value=Home页面。怎样才能使MyKey在_LoginPartial中可用?
谢谢!
发布于 2018-08-06 21:00:54
问题是,您试图在控制器的构造函数中设置ViewData内容。
ViewData字典实际上不是由控制器创建的。它是在MVC管道中的一个非常不同的点创建的,然后注入到控制器中。基本上,您可以将此过程看作如下所示:
// create controller
var controller = CreateController<MyController>();
// do stuff
// inject ViewData
controller.ViewData = GetViewDataDictionary();
// invoke controller action
var result = controller.SomeAction();因此,ViewData是在创建控制器之后提供的;在其构造函数运行之后。因此,构造函数中对视图数据的任何赋值都不适用于实际的视图数据字典。
因此,您需要在不同的时间设置这些值,因此不能在那里使用构造函数。一般来说,使用ViewData在某种程度上是遗留的构造,如果可能的话,您应该尽量避免。相反,您应该使用强类型的视图模型对象。当然,这将要求您在每个操作中显式地传递数据,但这样也不会引入任何隐式数据流。
如果您正在做的事情实际上总是应用于_LoginPartial,那么另一种方法尤其有用,那就是使用一个视图组件。视图组件是您可以在视图中使用的可重用组件,这些组件的行为与控制器操作类似。因此,您只需将一个视图组件插入到您的部分中,并让它运行逻辑(异步地均匀运行!)提供数据库中的数据。而且你也不需要在任何控制器上乱搞才能让它工作。
发布于 2018-08-07 02:17:04
ViewData可以在控制器激活后或通过过大的OnActionExecuting来访问。
// // Summary: // Gets or sets Microsoft.AspNetCore.Mvc.ViewFeatures.ViewDataDictionary used by // Microsoft.AspNetCore.Mvc.ViewResult and Microsoft.AspNetCore.Mvc.Controller.ViewBag. // // Remarks: // By default, this property is intiailized when Microsoft.AspNetCore.Mvc.Controllers.IControllerActivator // activates controllers. // This property can be accessed after the controller has been activated, for example, // in a controller action or by overriding Microsoft.AspNetCore.Mvc.Controller.OnActionExecuting(Microsoft.AspNetCore.Mvc.Filters.ActionExecutingContext). // This property can be also accessed from within a unit test where it is initialized // with Microsoft.AspNetCore.Mvc.ModelBinding.EmptyModelMetadataProvider. [ViewDataDictionary] public ViewDataDictionary ViewData { get; set; }
对于解决方案,您可以尝试过OnActionExecuting,如下所示:
public class BaseController : Controller
{
public ApplicationDbContext _db;
public BaseController(ApplicationDbContext db)
{
_db = db;
}
public override void OnActionExecuting(ActionExecutingContext context)
{
ViewData["MyKey"] = _db.Product.ToList();
base.OnActionExecuting(context);
}
}_LoginPartial.cshtml
@foreach (Product item in @ViewData["MyKey"] as IList<Product>)
{
<li><a>@item.Name</a></li>
}https://stackoverflow.com/questions/51713663
复制相似问题