在ASP.NET Core Identity登录分部视图中获取关联表用户全名
解决ASP.NET Core Identity中访问关联Person表时的空引用错误
问题原因
UserManager.GetUserAsync(User) 默认只会查询 ApplicationUser 表数据,不会自动加载关联的 Person 导航属性,导致 personResult.Person 为 null,访问 FullName 时触发"Object reference not set to an instance of an object."错误。
解决方案
方案1:自定义UserStore实现关联数据预加载
通过重写UserStore的查询方法,强制Include关联的Person表:
- 创建自定义UserStore类:
public class CustomUserStore : UserStore<ApplicationUser> { public CustomUserStore(DbContext context, IdentityErrorDescriber describer = null) : base(context, describer) { } public override async Task<ApplicationUser> FindByIdAsync(string userId, CancellationToken cancellationToken = default) { return await Users.Include(u => u.Person) .FirstOrDefaultAsync(u => u.Id == userId, cancellationToken); } public override async Task<ApplicationUser> FindByNameAsync(string normalizedUserName, CancellationToken cancellationToken = default) { return await Users.Include(u => u.Person) .FirstOrDefaultAsync(u => u.NormalizedUserName == normalizedUserName, cancellationToken); } }
- 在Program.cs(或Startup.cs)中注册自定义UserStore:
services.AddIdentity<ApplicationUser, IdentityRole>() .AddUserStore<CustomUserStore>() .AddDefaultTokenProviders();
之后使用UserManager.GetUserAsync(User)就能自动获取关联的Person数据,无需修改分部视图代码。
方案2:在分部视图中直接通过DbContext加载关联数据
注入DbContext,显式Include Person表,并使用异步查询避免死锁:
修改Login Partial视图:
@using Microsoft.AspNetCore.Identity @using Models; @using System.Security.Claims; @inject SignInManager<ApplicationUser> SignInManager @inject ApplicationDbContext DbContext <ul class="navbar-nav"> @if (SignInManager.IsSignedIn(User)) { <li class="nav-item"> @{ var userId = User.FindFirstValue(ClaimTypes.NameIdentifier); var user = await DbContext.Users.Include(u => u.Person) .FirstOrDefaultAsync(u => u.Id == userId); var fullName = user?.Person?.FullName ?? User.Identity?.Name; } <a class="nav-link text-dark" asp-area="Identity" asp-page="/Account/Manage/Index" title="Manage">Hello @fullName!</a> </li> <li class="nav-item"> <form class="form-inline" asp-area="Identity" asp-page="/Account/Logout" asp-route-returnUrl="@Url.Page("/", new { area = "" })" method="post" > <button type="submit" class="nav-link btn btn-link text-dark">Logout</button> </form> </li> } else { <li class="nav-item"> <a class="nav-link text-dark" asp-area="Identity" asp-page="/Account/Register">Register</a> </li> <li class="nav-item"> <a class="nav-link text-dark" asp-area="Identity" asp-page="/Account/Login">Login</a> </li> } </ul>
额外检查
确保数据库中ApplicationUser的PersonID字段已正确关联到Person表中存在的记录,避免因数据关联错误导致Person为null。
内容的提问来源于stack exchange,提问作者Reafidy
相关产品推荐
相关产品推荐

