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

提交表单或刷新页面后Courts属性值丢失问题排查

问题:提交表单或刷新页面时Courts属性返回null,无法保留值

我添加了一个用于存储列表值的属性,但提交表单或刷新页面时,Courts属性返回null,无法保留值。

后端代码

[BindProperty]
public List<Courts> Courts { get; set; } // Define the property

// Existing request property
[BindProperty]
public BookRequest Request { get; set; }

public async Task<IActionResult> OnGetAsync()
{
    if (Courts == null) // Load the courts only if it's not already loaded
    {
        Courts = (List<Courts>)await _requestRepository.GetAllCourtsAsync();
    }

    return Page();
}

public async Task<IActionResult> OnPostAsync()
{
    if (!ModelState.IsValid)
    {
        if (Courts == null) // Load the courts only if it's not already loaded
        {
            Courts = (List<Courts>)await _requestRepository.GetAllCourtsAsync();
        }

        return Page();
    }

    try
    {
        // Save the request to the database
        await _requestRepository.AddAsync(Request);
    }
    catch (Exception ex)
    {
        ViewData["Notification"] = new Notification
        {
            Type = Enums.NotificationType.Error,
            Message = "Something went wrong" + ex.Message
        };

        return Page();
    }

    return RedirectToPage("./List");
}

视图代码

<div class="form-group">
    <label asp-for="Request.CourtId">Court</label>
    <select asp-for="Request.CourtId" class="form-control" required>
        <option value="">Select a court</option>
        @foreach (var court in Model.Courts)
        {
            <option value="@court.Id">@court.Name</option>
        }
    </select>
    <span asp-validation-for="Request.CourtId" class="text-danger"></span>
</div>

原因及解决方法

核心原因

  1. [BindProperty]的模型绑定逻辑
    你给Courts添加了[BindProperty],但表单提交时前端并没有传递Courts的任何数据。模型绑定只会将请求中存在的参数赋值给对应属性,不存在的参数会被设为默认值(引用类型就是null),所以Post请求后Courts会变成null。

  2. 页面模型的无状态特性
    ASP.NET Core Razor Pages的页面模型是无状态的,每次请求(包括刷新页面的Get请求、表单提交的Post请求)都会创建新的模型实例。你之前的if (Courts == null)判断看似合理,但实际上每次请求时Courts初始都是null,这个判断并没有起到“避免重复加载”的作用,反而可能在某些场景下遗漏加载。

解决步骤

1. 移除Courts的[BindProperty]特性

Courts是渲染下拉框的数据源,不需要接收前端提交的数据,因此不需要绑定属性。移除[BindProperty]可以避免模型绑定将其设为null:

// 移除[BindProperty]
public List<Courts> Courts { get; set; } 

[BindProperty]
public BookRequest Request { get; set; }

2. 确保所有需要渲染页面的场景都加载Courts

不管是初始Get请求、Post验证失败返回页面,还是Post异常返回页面,都要主动加载Courts,不要依赖null判断(因为每次实例都是新的,Courts必然为null):

public async Task<IActionResult> OnGetAsync()
{
    // 直接加载Courts,无需判断
    Courts = await _requestRepository.GetAllCourtsAsync();
    return Page();
}

public async Task<IActionResult> OnPostAsync()
{
    if (!ModelState.IsValid)
    {
        // 验证失败返回页面时,必须加载Courts
        Courts = await _requestRepository.GetAllCourtsAsync();
        return Page();
    }

    try
    {
        await _requestRepository.AddAsync(Request);
    }
    catch (Exception ex)
    {
        ViewData["Notification"] = new Notification
        {
            Type = Enums.NotificationType.Error,
            Message = "Something went wrong" + ex.Message
        };
        // 异常返回页面时同样需要加载Courts
        Courts = await _requestRepository.GetAllCourtsAsync();
        return Page();
    }

    return RedirectToPage("./List");
}

3. 额外优化(可选)

如果GetAllCourtsAsync()的返回值本身就是List<Courts>,可以去掉强制类型转换(List<Courts>),避免不必要的类型转换风险。


内容的提问来源于stack exchange,提问作者nick glav

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.10 11:52:41