Как правильно расширить ApplicationUser в ASP.NET MVC? - PullRequest
0 голосов
/ 28 ноября 2018

Это моя первая попытка использовать удостоверение 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. Поля типа SteamId, Credits или RegisterDate сохраняются в виде строки в таблице AspNetUserClaims, и мне необходимо преобразовать их в int, long или DateTime в методе расширения
  3. Мне нужно написать метод расширения для каждого свойства, которое я добавлю к ApplicationUser

Каков наилучший способ обработки дополнительных полей?

  • Может ли быть возможность создать новый объект с именем AdditionalUserInformation и сохранить сериализованную строку json в качестве заявки и иметь только один метод расширения для возврата объекта?Тогда свойства будут иметь правильный тип.
  • Или есть способ получить доступ к свойствам ApplicationUser в представлении?
  • Или проблема заключается в использовании тех, что в представлении?Должен ли я получить к ним доступ в контроллере и создать модель для представления, содержащего всю информацию?А как насчет страницы _Layout или частичного представления _navigation?Им также может понадобиться информация пользователя.Я думаю, что я не могу кормить их с контроллерами.

Я также проверил несколько примеров.В основном они добавляют эти методы расширения и в основном просто строковые свойства.

Примеры

В данный момент я застрял здесь в поиске лучшего и, возможно, чистого решения.

1 Ответ

0 голосов
/ 28 ноября 2018

Вы можете получить доступ к таблице AspNetUsers с именем «Users» из вашего DbContext.Сначала запросите у AspNetUsers имя пользователя или идентификатор текущего пользователя, затем заполните свою модель представления и отправьте ее в представление.Следующий код показывает, что я описал:

[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; }
}
...