You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

ASP.NET Core MVC获取登录用户关联数据及显示异常排查

问题产生原因

核心问题是Razor视图辅助方法用错:

  • @Html.DisplayNameFor() 方法的作用是输出模型属性的显示名称(未配置[Display]特性时直接返回属性名的文本),不会读取属性存储的实际值,所以这里直接输出了属性名account,和后台查到的数据没有关联。
  • 额外隐患:你在IndexModel中定义的user、account是公共字段,不是公共属性。Razor Pages的模型绑定、视图访问逻辑默认针对属性设计,使用字段在部分场景下会出现访问异常。
修复步骤
  1. 修正后端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);
                }
            }
        }
    }
    
  2. 修正前端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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.30 03:45:36