【问题标题】:How to set global viewmodels in ASP .NET Core 3.1?如何在 ASP .NET Core 3.1 中设置全局视图模型?
【发布时间】:2025-10-16 10:55:01
【问题描述】:

我是 ASP.NET Core 的新手,在将全局模型和视图模型绑定到 razor 视图时遇到了一些麻烦。我的应用程序是 Web API 和 MVC 与 razor 视图的混合体。

我的目标

当我打开一个 ASP.NET MVC 页面时,我需要根据 cookie 中接收到的 id 从数据库(DbContext 服务)加载模型来实例化模型。我想在每个视图或局部视图中全局使用这个模型对象。

当前实施

我可以在页面控制器的操作方法中访问 c​​ookie,因此我必须在每个操作方法中从 DbContext 加载模型并将其作为视图模型绑定到目标视图。这是不切实际的,因为我必须在每个页面控制器中都这样做,因为我需要在导航窗格中的所有页面上使用该模型对象。

想法

我认为应该可以访问 Startup.cs 中的 Cookies 和 dbcontext 并将模型对象绑定到 _ViewStart.cshtml,以便在每个视图或部分视图中都可以全局访问它。即使这种方法是正确的,我也不知道代码会是什么样子。因为我现在正在通过边做边学和试错来学习使用 .NET Core 的 Web 应用程序。 :(

更新

我有一个布局页面_Layout.cshtml,其中包括像_NavPane.cshtml 这样的部分视图。我的目标是将 Model 对象传递给 _Layout,它是通过从数据库加载来实例化的(为此我有一个服务 IMandantRepository)并依赖于一个 cookie。

每个页面请求都需要该模型对象。这就是为什么在 MVC 页面控制器之外加载模型对象并将其传递给它们(我无法从技术上实现)是一种更好的做法。

我试图自己找到一个解决方案,最终得到了临时的丑陋解决方案。以下是_ViewStart 文件的内容。在底部,我分配了所需的全局变量,我可以在每个视图或局部视图中使用它们。

这种方案至少有两个缺点:

  1. 模型对象可能被冗余加载。
  2. 视图文件中的程序逻辑过多。
    @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;
}

【问题讨论】:

  • I need that model object on all pages in my navigation page 您是否尝试过将导航放在布局页面中?如果您想根据存储在db中的数据生成导航,您可以实现并使用自定义服务来查询数据,然后您可以在布局中调用该服务并为导航菜单提供数据。
  • @FeiHan 谢谢你的回答。我更新了我的问题,对视图布局和我的中间解决方案进行了一些解释。对我来说完美的解决方案是在 MVC 页面控制器之外加载模型对象并将其传递给页面控制器和布局视图或全局使用它。

标签: asp.net-core-mvc asp.net-core-3.1 asp.net-mvc-viewmodel


【解决方案1】:

这是Startup.csConfigureService() 中的示例代码。你可以通过这种方式注册你的dbContext类。

services.AddDbContext<BookStoreContext>( options =>
        options.UseSqlServer(_configuration.GetConnectionString("DefaultConnection")));

【讨论】:

  • 感谢您的回答。我用中间解决方案更新了我的问题,这不是最佳实践。我想一个更好的解决方案可能如下使用 Startup.cs string mycookie = app.ApplicationServices.GetService().HttpContext.Request.Cookies['myCookie']; 中的 Confiure() 方法var myModel = app.ApplicationServices.GetService().GetMandantByAbbr(mycookie); // 如何将 myModel 注入 _Layout.cshtml 或从 _Layout.csthml 访问它???
  • 在我上一条评论中忘记将代码添加到 Startup.cs 的想法。这是初学者的错误。启动方法仅在 Web 应用程序主机启动时执行一次。 :) 我相信我需要一个读取 cookie 并设置全局模型对象的中间件。但悬而未决的问题是如何将全局对象传递给 _Layout.cshtml...
最近更新 更多