Razor Page调用OnPostResend时属性被设为null的原因及解决方法
问题原因与解决方案
原因分析
- 表单未携带关键参数:
LoginType和DocumentNumber虽标记了[BindProperty],但点击"Reenviar código"按钮提交的表单里,没有包含这两个属性的输入字段。ASP.NET Core模型绑定仅能从请求内容(表单数据、查询字符串等)获取值,因此这两个属性会被设为null。 - 异步方法返回类型错误:
OnPostResendAsync使用async void返回类型,这在ASP.NET Core页面模型中是错误用法——该类型仅适用于UI事件处理,会导致框架无法跟踪异步操作完成状态,可能引发请求上下文提前释放等问题。
解决方案
步骤1:为第二个表单添加隐藏字段
修改.cshtml中的第二个表单,加入LoginType和DocumentNumber的隐藏输入,确保提交时携带这两个值(同时移除无效的<href>标签):
<form asp-page-handler="resend" method="post"> <input type="hidden" asp-for="LoginType" /> <input type="hidden" asp-for="DocumentNumber" /> <button id="resendToken" type="submit" class="btn btn-dark">Reenviar código</button> </form>
步骤2:修正异步方法返回类型
修改页面模型中的OnPostResendAsync方法,将返回类型改为Task<IActionResult>,并添加空值检查避免异常:
public async Task<IActionResult> OnPostResendAsync() { List<SATCloudUser> _users = _userManager.Users.Where(x => x.DocumentNumber == DocumentNumber).ToList(); if (_users.Count == 0) { // 处理用户不存在的异常情况 return Page(); } SATCloudUser _satUser = _users[0]; var token = await _userManager.GenerateTwoFactorTokenAsync(_satUser, "Email"); if(LoginType == "sms") { AlertsManager _alertManager = new AlertsManager(); string phoneNumber = "+57" + _satUser.PhoneNumber; string message = $"Código de inicio de sesión en Better Together SE: {token}. Por favor no comparta este código."; await _alertManager.SendTextMessageAsync(phoneNumber, message); } else if(LoginType == "email") { EmailManager _emailManager = new EmailManager(); await _emailManager.NewTokenEmail(_satUser.Email, token); } // 保留页面状态,返回当前页 TempData["PhoneNumber"] = _satUser.PhoneNumber; return Page(); }
额外优化建议
- 第一个表单也建议添加
LoginType和DocumentNumber的隐藏字段,避免后续模型绑定出现意外问题。 - 所有查询用户的逻辑都应添加空值检查,防止因用户不存在引发索引越界异常。
内容的提问来源于stack exchange,提问作者Luz Vera
相关产品推荐
相关产品推荐

