ASP.NET Core Razor Pages 为List类型模型属性创建表单多值录入遇问题求助
现有代码问题点
- JS中使用
getElementById获取class为Category-Container的容器,返回值为null,导致添加元素逻辑执行报错,这是只能添加2个输入框的核心原因 - 动态生成的
input的name属性不符合Razor Pages集合绑定规则,后端无法正确映射到绑定属性 asp-for直接绑定List<T>类型的Addresses/Categories本身是错误的,应该绑定到泛型类的内部属性- 集合属性没有初始化空实例,服务端渲染初始表单时会触发空引用异常
修复方案
1. 修正Model定义
为Address、Category补充业务属性,同时初始化集合避免空引用:
public class Address { // 示例属性,可根据业务调整 public string Street { get; set; } } public class Category { // 示例属性,可根据业务调整 public string Name { get; set; } } public class FormInput { public List<Address> Addresses { get; set; } = new(); public List<Category> Categories { get; set; } = new(); }
2. 修正Razor页面HTML
给容器添加正确的id,初始输入框使用带索引的绑定规则:
<form method="post"> <!-- 地址模块 --> <ul id="AddressContainer"> <li class="row"> <div class="col-8"> <input asp-for="_Input.Addresses[0].Street" type="text" class="w-100" /> </div> <div class="col"> <button type="button" class="btn btn-primary" onclick="AddNewItem('AddressContainer', '_Input.Addresses', 'Street')"> 新增地址 </button> </div> </li> </ul> <!-- 分类模块 --> <ul id="CategoryContainer"> <li class="row"> <div class="col-8"> <input asp-for="_Input.Categories[0].Name" type="text" class="w-100" /> </div> <div class="col"> <button type="button" class="btn btn-primary" onclick="AddNewItem('CategoryContainer', '_Input.Categories', 'Name')"> 新增分类 </button> </div> </li> </ul> <button type="submit">提交表单</button> </form>
3. 重写JS动态添加逻辑
按照Razor集合绑定规则生成name属性,通用方法支持多字段复用:
function AddNewItem(containerId, fieldPrefix, propertyName) { const container = document.getElementById(containerId); // 计算当前已有项数量作为新项的索引,索引必须从0开始连续递增 const currentIndex = container.querySelectorAll('li').length; const row = document.createElement('li'); row.classList.add('row'); // 组装输入框 const inputCol = document.createElement('div'); inputCol.classList.add('col-8'); const input = document.createElement('input'); input.classList.add('w-100'); // 核心:name格式必须为 绑定属性名[索引].子属性名 input.name = `${fieldPrefix}[${currentIndex}].${propertyName}`; input.type = 'text'; inputCol.appendChild(input); // 组装按钮 const btnCol = document.createElement('div'); btnCol.classList.add('col'); const addBtn = document.createElement('button'); addBtn.classList.add('btn', 'btn-primary'); addBtn.innerText = '新增'; addBtn.type = 'button'; addBtn.onclick = () => AddNewItem(containerId, fieldPrefix, propertyName); btnCol.appendChild(addBtn); row.appendChild(inputCol); row.appendChild(btnCol); container.appendChild(row); }
注意事项
- Razor Pages集合绑定的核心要求是
name属性的索引从0开始连续不中断,只要符合该规则,添加任意数量的输入框都可以正常提交 - 如果业务需要支持删除表单项,删除后需要遍历剩余输入框重新赋值索引,避免索引中断导致后端漏收数据
- 不需要保留每行新增按钮的话,可以把新增按钮移到容器外部,索引计算逻辑保持不变即可
内容的提问来源于stack exchange,提问作者Myles Frazier
相关产品推荐
相关产品推荐

