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

时间:2018-11-28 17:55:42

标签: c# asp.net-mvc asp.net-identity-2

这是我第一次尝试通过内置身份验证使用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表中创建新列。问题是,我无法在视图中访问这些值。为此,如果我理解正确,则需要使用声明。这些声明存储在另一个名为AspNetUserClaims的表中。所以我必须向用户添加这些声明

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表中,一次作为AspNetUserClaims中的新条目存储
  2. 诸如SteamIdCreditsRegisterDate之类的字段作为字符串保存在AspNetUserClaims表中,我必须将它们转换为int,{{ 1}}或扩展名方法中的long
  3. 我必须为要添加到DateTime
  4. 的每个属性编写扩展方法

处理其他字段的最佳方法是什么?

  • 是否可以选择创建一个名为ApplicationUser的新对象并将json序列化的字符串存储为声明,并且只有一种扩展方法可以返回该对象?然后,这些属性将具有正确的类型。
  • 还是有一种方法可以在视图中访问AdditionalUserInformation的属性?
  • 还是在视图中使用这些问题?是否应该在控制器中访问它们并为包含所有信息的视图创建模型?那么_Layout页面或_navigation部分视图呢?他们可能还需要用户的信息。我想我不能用控制器喂它们。

我也检查了一些例子。通常,它们会添加那些扩展方法,而大多数只是字符串属性。

示例

我目前在寻找最佳且可能是干净的解决方案方面有些困惑。

1 个答案:

答案 0 :(得分:0)

您可以从DbContext中以名称“ Users”访问AspNetUsers表。首先使用当前用户的用户名或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; }
}