在 ASP.NET Core 中缓存导航栏链接

Posted

技术标签:

【中文标题】在 ASP.NET Core 中缓存导航栏链接【英文标题】:Caching navbar links in ASP.NET Core 【发布时间】:2021-12-09 06:02:15 【问题描述】:

我有一个 ASP.NET Core 应用程序,它根据用户的角色显示不同的导航栏链接。

它首先检查用户是否登录。如果是,则从数据库中检索名称和角色。然后使用角色上的 switch 语句呈现导航栏链接。这在我的 _LoginPartial.cshtml 中,我包含在我的 _Layout.cshtml 中:

@inject SignInManager<AppUser> SignInManager
@inject UserManager<AppUser> UserManager

@if (SignInManager.IsSignedIn(User))

    string name = UserManager.Users
        .Where(u => u.Id == UserManager.GetUserId(User))
        .Select(u => u.AppUser.FirstName + " " + u.AppUser.LastName)
        .FirstOrDefault();

    var usr = await UserManager.GetUserAsync(User);
    string role = (await UserManager.GetRolesAsync(usr))
        .FirstOrDefault();

    <ul class="navbar-nav mr-auto mt-2 mt-lg-0 d-lg-flex justify-content-center flex-fill ">
        <li class="nav-item ">
            <a class="nav-link text-dark text-uppercase font-size-xlarge font-weight-light" asp-area="" asp-controller="Home" asp-action="Index">Home</a>
        </li>
        @switch (role)
        
            case "Student": 
                <li class="nav-item">
                   <a class="nav-link" asp-area="Exams" asp-controller="Schedules" asp-action="Index">Exams</a>
                </li>
                @* More student-specific links here *@
                break;

            case "Instructor":
                <li class="nav-item">
                   <a class="nav-link" asp-area="Programs" asp-controller="Programs" asp-action="Index">Programs</a>
               </li> 
                @* More instructor-specific links here *@
                break;

            case "Administrator":
                @* Admin-specific links here *@ 
                break;
        
    </ul>
    

我想缓存这些链接以避免每次为每个用户从数据库中获取用户的角色和名称。由于此代码是布局文件的一部分,因此它会针对每个页面执行。

如何使用缓存标签助手缓存因角色而异的导航链接列表?我尝试过这样的事情:

<cache vary-by="@role">
     <ul class="navbar-nav mr-auto mt-2 mt-lg-0 d-lg-flex justify-content-center flex-fill ">
            <li class="nav-item ">
                <a class="nav-link text-dark text-uppercase font-size-xlarge font-weight-light" asp-area="" asp-controller="Home" asp-action="Index">Home</a>
            </li>
        @switch (role) 
        ...
    </ul>
</cache>

但是,我不太确定这是否提供任何性能优势,因为这不会阻止往返数据库以读取用户的名称和角色。是否有任何解决方法可以用来缓存这些因角色而异的导航栏链接?我没有为我的应用程序使用任何分布式缓存服务。还是应该通过注入IMemoryCache 来完成?我错过了什么?

【问题讨论】:

【参考方案1】:

如果目标是减少对数据库的调用,我可以看到下一个选项:

    您需要将 角色 保存在某处 - 例如通过使用会话。 或将输出缓存更改为因用户而异:
<cache vary-by-user>
    或使用声明而不是角色。无需任何数据库查询即可从 ClaimsPrincipal 中检索声明列表。

【讨论】:

以上是关于在 ASP.NET Core 中缓存导航栏链接的主要内容,如果未能解决你的问题,请参考以下文章

在 ASP.Net Core Web 应用程序(引导程序)中向导航栏添加下拉菜单

ASP.NET MVC C# 如何分隔导航栏链接?

如何在 ASP.Net Core MVC 中使用 HTML 链接?

(asp.net) Bootstrap 4 导航栏切换器不工作

使用 jQuery 动态突出显示我的导航栏链接的最佳选择?

在导航栏折叠时隐藏的导航栏中显示图像