问题描述
我是 ASP.NET Core 的新手,在将全局模型和视图模型绑定到剃刀视图时遇到了一些麻烦。我的应用程序是 Web API 和 MVC 与剃刀视图的混合体。
我的目标
当我打开一个 ASP.NET MVC 页面时,我需要根据在 cookie 中收到的 id 从数据库(DbContext
服务)加载它来实例化一个模型。我想在每个视图或局部视图中全局使用这个模型对象。
当前实施
我可以在页面控制器的操作方法中访问 cookie,因此我必须在每个操作方法中从 DbContext 加载模型并将其作为视图模型绑定到目标视图。这不切实际,因为我必须在每个页面控制器中执行此操作,因为我需要在导航窗格中的所有页面上使用该模型对象。
想法
我认为应该可以在 Startup.cs 中访问 Cookies 和 dbcontext 并将模型对象绑定到 _ViewStart.cshtml,以便在每个视图或部分视图中都可以全局访问它。即使这种方法是正确的,我也不知道代码会是什么样子。因为我正在通过边做边学和尝试和错误来学习 .NET Core 的 Web 应用程序。 :(
更新
我有一个布局页面 _Layout.cshtml
,其中包含部分视图,例如 _NavPane.cshtml
。我的目标是将 Model 对象传递给 _Layout,该对象通过从数据库加载实例化(为此我有一个服务 IMandantRepository
)并依赖于 cookie。
每个页面请求都需要该模型对象。这就是为什么在 MVC 页面控制器之外加载模型对象并将其传递给它们是更好的做法(我无法在技术上实现)。
我试图自己找到解决方案,但最终采用了临时丑陋的解决方案。以下是 _ViewStart
文件的内容。在底部,我分配了所需的全局变量,我可以在每个视图或部分视图中使用它们。
这个解决方案至少有两个缺点:
- 模型对象可能被冗余加载。
- 视图文件中的程序逻辑过多。
@inject MyProject.Data.IMandantRepository mandantRepo
@{
// Main layout template
Layout = "_Layout";
// Define default values
bool showAdminSection = false;
string src = "/images/logos/nologo.png";
// Read cookie value
string currentMandantUid;
Context.Request.Cookies.TryGetValue("currentMandant",out currentMandantUid);
// Load mandant from the database
var thisMandant = mandantRepo.GetMandantByUid(currentMandantUid);
if(thisMandant is Mandant){
src = "data:image/*;base64," + thisMandant.GetBase64logo();
showAdminSection = thisMandant.Abbr == "AdminMandant";
}
// Assing global variables to ViewData
ViewData["CurrentMandant"] = thisMandant;
ViewData["logoSrc"] = src;
ViewData["showAdminSection"] = showAdminSection;
}
解决方法
这是 Startup.cs
的 ConfigureService() 中的示例代码。您可以通过这种方式注册您的 dbContext
课程。
services.AddDbContext<BookStoreContext>( options =>
options.UseSqlServer(_configuration.GetConnectionString("DefaultConnection")));