#c# #asp.net-core #entity-framework-core
#c# #asp.net-core #entity-framework-core
Вопрос:
В настоящее время есть ApplicationUser
класс с некоторыми пользовательскими свойствами, например:
public class ApplicationUser : IdentityUser
{
public string Name { get; set; }
public List<Content> Content { get; set; }
}
Я хотел бы получить текущего зарегистрированного пользователя со списком связанных данных ( Content
свойств).
В моем контроллере, если я поставлю:
Applicationuser user = await _userManager.GetUserAsync(HttpContext.User);
Я получаю зарегистрированного пользователя, но без каких-либо связанных данных.
Но, если я получу текущего пользователя, используя ApplicationDbContext
, как показано ниже, я смогу получить связанные данные:
ApplicationUser user = await _userManager.GetUserAsync(HttpContext.User);
ApplicationUser userWithContent = _context.Users.Include(c => c.Content).Where(u => u.Id == user.Id).ToList();
Но это не отображается правильно для меня!
Есть идеи?
Комментарии:
1. Используйте
var userId = _userManager.GetUserId(HttpContext.User)
вместо этого, то есть не запрашивая базу данных, а затем выполните быструю загрузку.
Ответ №1:
проверка исходного кода [UserManager][1]
GetUserAsync завершится вызовом FindByIdAsync
, который будет предоставлен IUserStore
реализацией. Просматривая исходный код в вопросе, очень вероятно, используя EFCore в качестве реализации IUserStore.
В случае EFCore здесь упоминалось, что Find
его нельзя комбинировать с include
, поэтому я спрашиваю, что вы сделали, чтобы выполнить быструю загрузку в вашем вопросе, на самом деле может быть правильным.
Ответ №2:
Если вам нужны эти свойства в каждом запросе, есть лучший способ получить их, не запрашивая базу данных в каждом запросе.
Вы можете сохранить эти свойства, Claims
написав свои собственные IUserClaimsPrincipalFactory<TUser>
и прочитав их из HttpContext.User
public class CustomUserClaimsPrincipalFactory : UserClaimsPrincipalFactory<ApplicationUser>
{
public CustomUserClaimsPrincipalFactory(UserManager<ApplicationUser> userManager, IOptions<IdentityOptions> optionsAccessor)
: base(userManager, optionsAccessor)
{
}
protected async override Task<ClaimsIdentity> GenerateClaimsAsync(ApplicationUser user)
{
ClaimsIdentity identity = await base.GenerateClaimsAsync(user);
identity.AddClaim(new Claim("Name", user.Name));
for (int i = 0; i < user.Content.Count; i )
{
string content = Newtonsoft.Json.JsonConvert.SerializeObject(user.Content[i]);
identity.AddClaim(new Claim("Content", content));
}
return identity;
}
}
Также вам необходимо зарегистрировать его в service collection
services.AddScoped<IUserClaimsPrincipalFactory<ApplicationUser>, CustomUserClaimsPrincipalFactory>();
Вы можете получить доступ к этим свойствам с помощью этого кода
string name = httpContext.User.FindFirstValue("Name");
List<Content> contents = new List<Content>();
foreach (Claim claim in httpContext.User.FindAll("Content"))
{
Content content = Newtonsoft.Json.JsonConvert.DeserializeObject<Content>(claim.Value);
contents.Add(content);
};