提交表单或刷新页面后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>
原因及解决方法
核心原因
[BindProperty]的模型绑定逻辑
你给Courts添加了[BindProperty],但表单提交时前端并没有传递Courts的任何数据。模型绑定只会将请求中存在的参数赋值给对应属性,不存在的参数会被设为默认值(引用类型就是null),所以Post请求后Courts会变成null。页面模型的无状态特性
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
相关产品推荐
相关产品推荐

