ASP.NET 只为所有视图核心填充模型一次

ASP.NET Core populate model only once for all views

我是 ASP.Net Core(在本例中为 3.0)的新手,我正在尝试创建一个在 WebApplication 的所有视图中都可见的菜单,该菜单是动态创建的并且只能填充一次.下面我将解释我为达到所需目标所做的步骤和尝试(如果需要,我可以分享我正在使用的代码)。

这是我做的:

  1. 以一种简单的方式,使用“_Layout.cshtml”页面,我创建了一个静态 HTML 菜单并使所有其他视图简单地继承该布局。到目前为止,还不错;
  2. 下一个挑战来自于菜单项是在用户登录后动态创建的,我设法通过在控制器中设置 ModelView 来克服这个问题(HomeController.csIndex action 在这种情况下),然后将其传递给视图。对于这种情况,工作正常,因为默认页面是 ~\Home\Index\,问题是当我用不同的控制器切换到不同的视图时,菜单必须再次呈现,所以我必须复制代码(一个问题基于 this postOnActionExecuted 创建一个 BaseController 和 BaseModel 来承载菜单生成代码)
  3. 现在,最大的问题是我只能在用户登录后填充菜单一次。每次在不同 controllers/views 之间存在重定向(post-相同 controller/view 的返回工作正常),OnActionExecuted 中的模型为空,我尝试使用 ViewData、ViewBag , TemData, 但都是空的。

所以,我的问题是,如何保持特定数据的活动和共享,基本上跨所有视图,并且只在不同视图的重定向之间填充一次(在每次用户登录后)? 我一直在阅读并找到了除我所做的解决方案之外的几种解决方案,但我没有发现任何可以按照我需要的方式在整个用户会话中保持数据活动的方案:

总结一下,我此刻的流程是这样的:

  1. 用户登录
  2. 重定向到默认值:~\Home\Index
  3. MenuModelView.cs 用于菜单构建,HomeController.cs returns 到 Index.cshtml 附有模型。
  4. Index.cshtml 接收填充的 ModelView 并使用 _Layout.cshtml
  5. _Layout.cshtml 根据 MenuModelView.cs 数据
  6. 为菜单构建 HTML 标签
  7. 用户导航到不同的视图并从特定的 controller/view
  8. 重复第 3 步到第 5 步

如果你想创建一个可以在所有页面中访问的控件而无需更改每个控制器,我强烈建议创建一个视图组件。因为 view component 与您的控制器没有关系,但可以访问数据库和完整 HTTP 上下文等依赖项。

例如,你想建立一个自定义的导航菜单,你可以只创建一个名为NavHeader

的视图组件
using Microsoft.AspNetCore.Mvc;

namespace YourProject.Views.Shared.Components.NavHeader 
{
    public class NavHeader : ViewComponent
    {
        public NavHeader(YourDbContext context)
        {
             // you can access your dependencies, like database.
        }

        public IViewComponentResult Invoke()
        {
            // your own logic. You can access HTTPContext here.
            var model = new YourOwnModel();
            return View(model);
        }
    }
}

只需在任何视图或布局中调用它即可。

<!DOCTYPE html>
<html>
<head>
    <title>Example</title>
</head>
<body>
    @*Render your component like this*@
    <vc:nav-header></vc:nav-header>
</body>

更多关于视图组件的内容,请参考:

https://docs.microsoft.com/en-us/aspnet/core/mvc/views/view-components?view=aspnetcore-3.1

https://anduin.aiursoft.com/post/2020/1/4/share-view-component-between-different-aspnet-core-web-project