【问题标题】:.NET Core 3.1 Razor Model in _Layout page_Layout 页面中的 .NET Core 3.1 Razor 模型
【发布时间】:2021-02-04 22:42:39
【问题描述】:

我有一个用户模型,其中包含登录名、姓名、权限、联系信息等内容。

我想在我的 _Layout 页面的菜单栏中显示用户名,以便在每个页面中显示。我可以在我的 _Layout 页面中显示这样的登录用户...

@User.Identity.Name.Replace(@"MYDOMAIN\", "")

但我想从模型中提取用户的真实姓名,并获得他们的权限来管理他们在公司 Intranet 网站上能看到和不能看到的内容。

问题是,如果我尝试在 _Layout 页面中设置页面模型,网站会崩溃,因为 _Layout 中的@RenderBody 会加载引用自己模型的其他页面。

也许我看错了,但是您如何维护整个网站的用户名和权限,而不让每个页面在每次进入新页面时都访问数据库?

另一种看待它的方式...... 假设您的菜单是数据驱动的,并且菜单存在于 _Layout 页面中。你是怎么做到的?

谢谢。

【问题讨论】:

    标签: .net asp.net-core razor razor-pages asp.net-core-3.1


    【解决方案1】:

    首先,如果不每次都访问数据库(至少是推荐的方式),就无法做到这一点,因为您获取的用户数据和权限可能会发生变化。

    其次,您可以在布局中使用@inject 并通过ClaimsPrincipal User 获取用户数据,这样您就可以这样做: @inject UserManager<TheUser> userManager.

    然后你可以这样做:var user=await userManager.FindByNameAsync(User.Identity.Name) 现在你用用户数据填充你的标签。

    类似这样的:

    _Layout.cshtml

    @inject UserManager<TheUser> userManager
    @{
       var user=await userManager.FindByNameAsync(User.Identity.Name)
    } 
    
    <div>
      @user.FullName
    </div>
    

    另一种方法是创建自定义“声明原则”工厂。是这样的:

    public class MyUserClaimsPrincipalFactory : UserClaimsPrincipalFactory<ApplicationUser> 
    {     
        public MyUserClaimsPrincipalFactory(
            UserManager<ApplicationUser> userManager,
            IOptions<IdentityOptions> optionsAccessor)
                : base(userManager, optionsAccessor)     
        {
        }
          
        protected override async Task<ClaimsIdentity>GenerateClaimsAsync(ApplicationUser user)
        {
             var identity = await base.GenerateClaimsAsync(user);
             identity.AddClaim(new Claim("FullName", user.FullName));         
             return identity;     
        } 
    }
    

    然后你把它添加到你的ConfigureServices:

    services.AddIdentity<ApplicationUser, IdentityRole>()
            .AddEntityFrameworkStores<ApplicationDbContext>()
            .AddClaimsPrincipalFactory<MyUserClaimsPrincipalFactory>(); 
    

    现在你可以像这样访问它

    User.FindFirst("FullName").Value
    

    ClaimsPrincipal User 也有一个 User.IsInRole 来检查用户角色。

    假设您的菜单是数据驱动的,并且菜单存在于 _Layout 页面中。你是怎么做到的?

    通常只针对数据,您可以将其缓存在服务器内存中,这样您就可以最大限度地减少数据库请求的数量(当“数据”被修改并重新缓存时清除缓存)但我建议不要这样做,因为您处理用户数据。

    【讨论】:

      猜你喜欢
      • 2020-11-16
      • 2020-05-26
      • 1970-01-01
      • 2020-07-09
      • 2020-05-06
      • 2020-07-09
      • 2020-04-04
      • 2019-12-20
      • 1970-01-01
      相关资源
      最近更新 更多