我已经创建了ASP.NET Core应用程序,现在我正在尝试在_LoginPartial中使用ViewBag。我已经创建了基本控制器:
<?xml version="1.0"?>
<mibscalar link="http://1.1.1.1/v1/mib/objs/inputPointGroupStatus?type=xml" type="readonly" name="inputPointGroupStatus">
<index name="index1">
<data index="1">
<index name="index2">
<data index="1" counter="0">
<bit index="1" value="false"/>
<bit index="2" value="false"/>
<bit index="3" value="false"/>
<bit index="4" value="false"/>
<bit index="5" value="false"/>
<bit index="6" value="false"/>
<bit index="7" value="false"/>
<bit index="8" value="false"/>
</data>
<data index="2" counter="0" />
<data index="3" counter="0" />
<data index="4" counter="0" />
<data index="5" counter="0" />
<data index="6" counter="0" />
<data index="7" counter="0" />
<data index="8" counter="0" />
<data index="9" counter="0" />
<data index="10" counter="0" />
<data index="11" counter="0" />
<data index="12" counter="0" />
<data index="13" counter="0" />
<data index="14" counter="0" />
<data index="15" counter="0" />
<data index="16" counter="0" />
</index>
</data>
<data index="2" />
<data index="3" />
<data index="4" />
<data index="5" />
<data index="6" />
<data index="7" />
<data index="8" />
<data index="9" />
<data index="10" />
</index>
</mibscalar>
我所有的控制器都来自此BaseController。
但是,当我在_LoginPartial.cshtml中看到ViewData时,只能看到它包含默认的Key = Title,Value = Home Page。我该怎么做才能在_LoginPartial中提供MyKey?
谢谢!
答案 0 :(得分:1)
问题是您试图在控制器的构造函数中设置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
,则该替代方法特别有用。 View components是可重用的组件,您可以在视图内部使用它们,它们的行为类似于控制器动作。因此,您只需将一个视图组件插入您的局部组件中,然后运行该逻辑(甚至异步!)来提供数据库中的数据。而且您无需弄乱任何控制器就可以正常工作。
答案 1 :(得分:0)
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>
}