如何正确扩展 ASP.NET MVC 中的 ApplicationUser?

How to extend the ApplicationUser in ASP.NET MVC correctly?

这是我第一次尝试使用内置身份验证的 ASP.NET 身份。之前的所有尝试都会导致手动检查用户凭据,然后设置 FormsAuthentication AuthCookie。但是我遇到了一些问题,signalR 连接没有这种方式的身份验证信息。所以我从头开始使用内置身份验证。

所以我用一些字段扩展了我的 ApplicationUser 对象:

public class ApplicationUser : IdentityUser
{
    public long SteamId { get; set; }
    public string Avatar { get; internal set; }
    public string Name { get; internal set; }
    public int Credits { get; internal set; }
    public long? DiscordId { get; internal set; }
    public DateTime? LastLogin { get; internal set; }
    public DateTime RegisterDate { get; internal set; }
}

这些字段将在我的 AspNetUsers table 中创建新列。问题是,我无法在我的视图中访问这些值。为此,如果我理解正确,我需要使用声明。这些声明存储在另一个名为 AspNetUserClaims 的 table 中。所以我必须将这些声明添加到用户

await UserManager.AddClaimAsync(user.Id, new Claim("Avatar", user.Avatar));

并创建一个扩展方法以从主体那里获取头像

public static class ClaimsPrincipalExtension
{
    public static string GetAvatar(this ClaimsPrincipal principal)
    {
        var avatar = principal.Claims.FirstOrDefault(c => c.Type == "Avatar");
        return avatar?.Value;
    }
}

现在我可以在我的视图中访问头像

@(((ClaimsPrincipal)User).GetAvatar())

我认为这不是一个非常好的和干净的方法,但这是我第一次使用它,所以我不知道最好的做法是什么。我不喜欢它的主要原因有以下三个:

  1. 头像存储了两次,一次在 AspNetUsers table 作为列,一次作为新条目在 AspNetUserClaims
  2. SteamIdCreditsRegisterDate 等字段在 AspNetUserClaims table 中保存为字符串,我必须将它们转换为 [=扩展方法中的 26=、longDateTime
  3. 我必须为每个 属性 编写一个扩展方法,我将添加到 ApplicationUser

处理附加字段的最佳方法是什么?

我也查了一些例子。大多数情况下,他们添加了那些扩展方法,而且大多只是字符串属性。

例子

我目前有点困于寻找最佳且可能是干净的解决方案。

您可以从 DbContext 访问名称为 "Users" 的 AspNetUsers table。首先使用当前用户的用户名或 userId 查询 AspNetUsers,然后填充您的 ViewModel 并将其发送到视图。以下代码显示了我所描述的内容:

[Authorize]
public ActionResult UserTopNavBar()
{
     var userTopNavBarViewModel = new UserTopNavBarViewModel();
     using(ApplicationDbContext _db = new ApplicationDbContext())
     {
         var user = _db.Users.FirstOrDefault(a => a.UserName == User.Identity.Name);
         if (user != null)
         {
             userTopNavBarViewModel.Name = user.FirstName + " " + user.LastName;
             userTopNavBarViewModel.Picture = user.Picture;
             userTopNavBarViewModel.Id = user.Id;
         }
     }
     return PartialView(userTopNavBarViewModel);
}

这是我的 ViewModel

public class UserTopNavBarViewModel
{
     public string Name { get; set; }
     public byte[] Picture { get; set; }
     public string Id { get; set; }
}