ASP.NET Core MVC获取登录用户关联数据及显示异常排查
问题产生原因
核心问题是Razor视图辅助方法用错:
@Html.DisplayNameFor()方法的作用是输出模型属性的显示名称(未配置[Display]特性时直接返回属性名的文本),不会读取属性存储的实际值,所以这里直接输出了属性名account,和后台查到的数据没有关联。- 额外隐患:你在
IndexModel中定义的user、account是公共字段,不是公共属性。Razor Pages的模型绑定、视图访问逻辑默认针对属性设计,使用字段在部分场景下会出现访问异常。
修复步骤
修正后端
Index.cshtml.cs代码- 把公共字段改为带
get;set;访问器的公共属性,命名符合C#帕斯卡命名规范 - 数据查询改用
FirstOrDefaultAsync并增加空判断,避免无对应账户时直接抛出空引用异常
修正后相关代码如下:
using Microsoft.EntityFrameworkCore; // 新增引用,支持异步查询方法 public class IndexModel : PageModel { private readonly ILogger<IndexModel> _logger; private readonly WebBankDbContext _context; private readonly UserManager<IdentityUser> _userManager; private readonly SignInManager<IdentityUser> _signInManager; // 改为公共属性 public IdentityUser? LoginUser { get; set; } public Account? UserAccount { get; set; } public IndexModel(SignInManager<IdentityUser> signInManager, UserManager<IdentityUser> userManager, ILogger<IndexModel> logger, WebBankDbContext context) { _logger = logger; _context = context; _userManager = userManager; _signInManager = signInManager; } public async Task OnGetAsync() { if (_signInManager.IsSignedIn(User)) { LoginUser = await _userManager.GetUserAsync(User); if (LoginUser != null) { // 异步查询当前用户的账户,空值时返回null不抛异常 UserAccount = await _context.Accounts .FirstOrDefaultAsync(st => st.UserId == LoginUser.Id); } } } }- 把公共字段改为带
修正前端
Index.cshtml视图代码- 移除视图中重复注入的
SignInManager、UserManager和重复的用户查询逻辑,直接访问PageModel中已经查询好的属性即可,减少冗余数据库请求 - 替换错误的
DisplayNameFor方法,直接读取账户的Amount属性值,可按需增加金额格式化、空值兜底
修正后相关代码如下:
@page @model IndexModel @{ ViewData["Title"] = "Home page"; } @if (User.Identity?.IsAuthenticated == true && Model.LoginUser != null) { <div class="text-center"> <h1 class="display-4">Welcome back, @(Model.LoginUser.Email?.Split("@")[0] ?? "user")</h1> </div> <div> <!-- 直接输出金额值,用C格式符自动渲染为货币格式,空值时兜底显示0.00 --> <h5>Your balance: @(Model.UserAccount?.Amount.ToString("C") ?? "0.00")</h5> </div> } else { <div class="text-center"> <h1 class="mb-3">Welcome, new one here? Go on and create account!</h1> </div> }- 移除视图中重复注入的
补充说明
如果需要展示字段的显示名称(比如给表单label用),才需要用DisplayNameFor或DisplayFor相关辅助方法,直接输出数据值时直接访问模型属性即可,不需要调用这类名称/元数据渲染方法。
内容的提问来源于stack exchange,提问作者dokichan
相关产品推荐
相关产品推荐

