如何正确扩展 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())
我认为这不是一个非常好的和干净的方法,但这是我第一次使用它,所以我不知道最好的做法是什么。我不喜欢它的主要原因有以下三个:
- 头像存储了两次,一次在
AspNetUsers
table 作为列,一次作为新条目在 AspNetUserClaims
SteamId
、Credits
或 RegisterDate
等字段在 AspNetUserClaims
table 中保存为字符串,我必须将它们转换为 [=扩展方法中的 26=、long
或 DateTime
- 我必须为每个 属性 编写一个扩展方法,我将添加到
ApplicationUser
处理附加字段的最佳方法是什么?
- 是否可以选择创建一个名为
AdditionalUserInformation
的新对象并将 json 序列化字符串存储为声明,并且只有一个 return 对象的扩展方法?然后属性将具有正确的类型。
- 或者有没有办法在视图中访问
ApplicationUser
的属性?
- 或者是视图中的使用问题?我应该在控制器中访问它们并为包含所有信息的视图创建模型吗?那么 _Layout 页面或 _navigation 局部视图呢?他们还可能需要用户的信息。我想我不能用控制器喂它们。
我也查了一些例子。大多数情况下,他们添加了那些扩展方法,而且大多只是字符串属性。
例子
- How should I access my ApplicationUser properties from within my MVC 6 Views?
我目前有点困于寻找最佳且可能是干净的解决方案。
您可以从 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; }
}
这是我第一次尝试使用内置身份验证的 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())
我认为这不是一个非常好的和干净的方法,但这是我第一次使用它,所以我不知道最好的做法是什么。我不喜欢它的主要原因有以下三个:
- 头像存储了两次,一次在
AspNetUsers
table 作为列,一次作为新条目在AspNetUserClaims
SteamId
、Credits
或RegisterDate
等字段在AspNetUserClaims
table 中保存为字符串,我必须将它们转换为 [=扩展方法中的 26=、long
或DateTime
- 我必须为每个 属性 编写一个扩展方法,我将添加到
ApplicationUser
处理附加字段的最佳方法是什么?
- 是否可以选择创建一个名为
AdditionalUserInformation
的新对象并将 json 序列化字符串存储为声明,并且只有一个 return 对象的扩展方法?然后属性将具有正确的类型。 - 或者有没有办法在视图中访问
ApplicationUser
的属性? - 或者是视图中的使用问题?我应该在控制器中访问它们并为包含所有信息的视图创建模型吗?那么 _Layout 页面或 _navigation 局部视图呢?他们还可能需要用户的信息。我想我不能用控制器喂它们。
我也查了一些例子。大多数情况下,他们添加了那些扩展方法,而且大多只是字符串属性。
例子
- How should I access my ApplicationUser properties from within my MVC 6 Views?
我目前有点困于寻找最佳且可能是干净的解决方案。
您可以从 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; }
}