ASP.NET Core单Razor视图多创建表单提交空数据问题
解决ASP.NET Core Razor视图表单提交空数据问题
核心问题分析
- Razor Pages模型绑定未启用:你的
IndexModel中proclist等属性未添加[BindProperty]特性,Razor Pages默认不会自动绑定POST请求中的数据到未标记该特性的公共属性。 - 表单字段名称与控制器参数不匹配:视图中
asp-for="proclist.DeviceId"生成的input标签name是proclist.DeviceId,但控制器接收的是Process data,模型绑定会寻找name为DeviceId的字段,导致无法匹配。 - Razor Pages与MVC控制器混用冲突:视图基于Razor Page(继承
PageModel),但提交到MVC控制器Action,绑定上下文不一致,容易导致数据丢失。
解决方案
方案一:使用Razor Pages内置Handler(推荐)
这种方式更符合Razor Pages的设计规范,避免混用问题。
1. 修改PageModel,添加绑定特性并实现Handler方法
public class IndexModel : PageModel { public List<Device> devicelist { get; set; } [BindProperty] // 启用POST数据绑定 public Process proclist { get; set; } public Extratime extras { get; set; } public Foodadd foods { get; set; } public void OnGet() { devicelist = new List<Device>(); proclist = new Process(); extras = new Extratime(); foods = new Foodadd(); } // 定义POST请求的Handler方法 public IActionResult OnPostAddTime() { if (!ModelState.IsValid) { // 模型验证失败时,重新加载页面数据并返回 devicelist = new List<Device>(); return Page(); } using (KoraContext db = new KoraContext()) { var tdevice = db.Devices.FirstOrDefault(x => x.Id == proclist.DeviceId); if (tdevice != null) // 避免空引用异常 { tdevice.Isbusy = "true"; db.Processes.Add(proclist); db.SaveChanges(); } return RedirectToPage("/Index"); } } }
2. 修改表单,指定Razor Pages Handler
<form method="post" asp-page-handler="AddTime" style="direction: rtl;"> <input type="hidden" asp-for="proclist.DeviceId" value="@item.Id" /> <input type="hidden" asp-for="proclist.Userid" value="@currentUser.Id" /> <div class="form-group"> <select asp-for="proclist.IsLimited" class="form-control" id="cc"> <option value="true">limited</option> <option value="false">Open</option> </select> </div> <div class="form-group" id="pp"> <input type="number" asp-for="proclist.hours" class="form-control home" placeholder="1.5" step=".01"> </div> <div class="form-group"> <select asp-for="proclist.IsSingle" class="form-control"> <option value="true">single</option> <option value="false">multi</option> </select> </div> <button type="submit" class="btn btn-primary">Enable</button> </form>
方案二:坚持使用MVC控制器接收
如果需要保留MVC控制器,需调整表单字段的name属性以匹配模型绑定规则。
1. 修改表单字段名称,去掉proclist前缀
将所有asp-for="proclist.XXX"替换为直接指定name属性,对应Process类的属性名:
<form method="post" asp-action="AddTime" style="direction: rtl;"> <input type="hidden" name="DeviceId" value="@item.Id" /> <input type="hidden" name="Userid" value="@currentUser.Id" /> <div class="form-group"> <select name="IsLimited" class="form-control" id="cc"> <option value="true">limited</option> <option value="false">Open</option> </select> </div> <div class="form-group" id="pp"> <input type="number" name="hours" class="form-control home" placeholder="1.5" step=".01"> </div> <div class="form-group"> <select name="IsSingle" class="form-control"> <option value="true">single</option> <option value="false">multi</option> </select> </div> <button type="submit" class="btn btn-primary">Enable</button> </form>
2. 优化控制器代码,增加验证与空值检查
public IActionResult AddTime(Process data) { if (data == null || !ModelState.IsValid) { return RedirectToAction("Index"); } using (KoraContext db = new KoraContext()) { var tdevice = db.Devices.FirstOrDefault(x => x.Id == data.DeviceId); if (tdevice != null) { tdevice.Isbusy = "true"; db.Processes.Add(data); db.SaveChanges(); } return RedirectToAction("Index"); } }
额外注意事项
- 每次提交后都要检查
ModelState.IsValid,确保数据符合模型校验规则。 - 对数据库查询结果进行空值检查,避免
NullReferenceException。 - 优先使用Razor Pages的Handler方法,减少MVC与Razor Pages混用带来的绑定问题。
内容的提问来源于stack exchange,提问作者Mohamed Yousef Khairlden
相关产品推荐
相关产品推荐

