Вопрос или проблема
Ну, я хочу выполнить начальную загрузку пользователя, потому что у меня есть таблицы, которые связаны с свойством UserId и с точным Id. Вот начальная загрузка для ApplicationUser:
public class ApplicationUserConfiguration : IEntityTypeConfiguration<ApplicationUser>
{
public void Configure(EntityTypeBuilder<ApplicationUser> builder)
{
builder.HasData(GenerateUsers());
}
private IEnumerable<ApplicationUser> GenerateUsers()
{
var hasher = new PasswordHasher<ApplicationUser>();
return new List<ApplicationUser>()
{
new ApplicationUser()
{
Id = "7ec4584c-ea3f-42e3-b862-2fb1e700fb6f",
UserName = "XXXX",
FirstName = "XXXX",
LastName = "XXXX",
ProfileImgUrl =
"XXXX",
PasswordHash = hasher.HashPassword(null, "XXXXX")
}
};
}
}
Проблема в том, что когда я пытаюсь запустить приложение, оно говорит:
NullReferenceException: ссылка на объект не указывает на экземпляр объекта.
Когда я отлаживаю, показывается, что приложение не может найти пользователя?:
@using Microsoft.AspNetCore.Identity
@using OnlineShop.Data.Models
@inject SignInManager<ApplicationUser> SignInManager
@inject UserManager<ApplicationUser> UserManager
<style>
.profile-img {
width: 70px;
height: 70px;
border-radius: 50%;
object-fit: cover;
margin-left: 20px;
}
</style>
<ul class="navbar-nav">
@if (SignInManager.IsSignedIn(User))
{
var user = await UserManager.GetUserAsync(User);
if (String.IsNullOrEmpty(user.ProfileImgUrl))
{
user.ProfileImgUrl = "https://st2.depositphotos.com/5682790/10456/v/450/depositphotos_104564156-stock-illustration-male-user-icon.jpg";
}
<li class="nav-item">
<a class="nav-link text-light" asp-area="Identity" asp-page="/Account/Manage/Index" title="Управление">Привет @user.FirstName @user.LastName ! <img src="@user.ProfileImgUrl" class="profile-img" /></a>
</li>
<li class="nav-item">
<form class="form-inline" asp-area="Identity" asp-page="/Account/Logout" asp-route-returnUrl="@Url.Action("Index", "Home", new { area = "" })">
<button type="submit" class="nav-link btn btn-link text-light mt-4">Выйти <i class="fa-solid fa-door-open"></i></button>
</form>
</li>
}
else
{
<li class="nav-item">
<a class="nav-link text-light" asp-area="Identity" asp-page="/Account/Register">Регистрация <i class="fa-solid fa-arrow-right-to-bracket"></i></a>
</li>
<li class="nav-item">
<a class="nav-link text-light" asp-area="Identity" asp-page="/Account/Login">Вход <i class="fa-solid fa-right-to-bracket"></i>
</a>
</li>
}
</ul>
Проблема здесь -> var user = await UserManager.GetUserAsync(User);
Переменная user равна null.
Есть идеи?
Ответ или решение
Конечно! Давайте подробно разберём вашу проблему с начальными данными (seeding) для пользователей в Entity Framework, чтобы устранить ошибку NullReferenceException
.
Обзор проблемы
Вы пытаетесь выполнить инициализацию пользователя с помощью конфигурации ApplicationUserConfiguration
, добавляя пользователя в базу данных с помощью метода HasData()
. Однако вы столкнулись с ошибкой, указывающей на то, что запрашиваемый пользователь не найден, когда вы вызываете UserManager.GetUserAsync(User)
.
Причины возникновения NullReferenceException
-
Пользователь не инициализирован: Судя по вашему коду, Пользователь с заданным
Id
должен инициализироваться при помощи методаSeed
, однако, если данная инициализация не была выполнена или произошла ошибка во время миграции, пользователь не будет найден. -
Не по правильному Id: Проверьте, действительно ли
UserId
вGetUserAsync(User)
соответствует томуId
, который вы указали в конфигурации. -
Ошибка пароля: Использование
PasswordHasher
может быть тоже затруднительным, если запрашиваемый пароль не совпадает с хешем. В вашем случае, передачаnull
может привести к проблемам.
Рекомендации по решению проблемы
1. Проверьте миграции базы данных
Возможно, пользователи еще не были добавлены в базу данных. Убедитесь, что у вас актуальная миграция, и она была применена успешно.
Используйте следующие команды в Package Manager Console или терминале:
Add-Migration InitialCreate
Update-Database
2. Убедитесь, что пользователь корректно создаётся
Проверьте метод GenerateUsers
и уточните, инициализируется ли массив пользователей правильно, особенно проверьте параметры замены полей и их доступность. Например, вы можете создать пользователя следующим образом:
private IEnumerable<ApplicationUser> GenerateUsers()
{
var hasher = new PasswordHasher<ApplicationUser>();
string userPassword = "YourPasswordHere"; // Определите пароль
return new List<ApplicationUser>()
{
new ApplicationUser()
{
Id = Guid.NewGuid().ToString(),
UserName = "testuser@example.com",
NormalizedUserName = "TESTUSER@EXAMPLE.COM", // Возможно, вам следует добавить
Email = "testuser@example.com",
NormalizedEmail = "TESTUSER@EXAMPLE.COM", // Возможно, вам следует добавить
FirstName = "Имя",
LastName = "Фамилия",
ProfileImgUrl = "URL_к_изображению",
PasswordHash = hasher.HashPassword(null, userPassword)
}
};
}
Здесь, возможно, вы должны также добавить нормализованные значения для имен пользователей и их электронной почты.
3. Проверьте инициализацию данных в Startup.cs
Убедитесь, что метод EnsureCreated()
или Migrate()
вызывается в вашем DbContext
, чтобы убедиться, что начальные данные загружаются:
using (var scope = app.ApplicationServices.CreateScope())
{
var dbContext = scope.ServiceProvider.GetService<ApplicationDbContext>();
dbContext.Database.Migrate();
SeedData.Initialize(dbContext);
}
Заключение
После выполнения этих шагов вы должны удостовериться, что ваш пользователь инициализирован корректно и база данных содержит все необходимые данные. Это должно устранить проблему с получением пользователя и, как следствие, исключение NullReferenceException
.
Если вы всё равно будете сталкиваться с проблемами, детально проверьте логи вашей системы и отладьте процесс инициализации данных, чтобы найти возможные ошибки.