ASP.NET Core如何通过单个表单提交多个用户注册请求?
ASP.NET Core 不定量用户批量注册实现方案
要实现数量不固定的多用户批量注册、无需为每个用户单独提交表单,可参考以下完整可运行实现:
问题处理记录
- 最初遇到控制器POST方法绑定失败、
Users返回null的问题,给控制器方法添加[Bind("Users")]后null问题解决,但又出现行索引匹配异常问题 - 最终解决方案:添加
<input type="hidden" name="Users.Index" value="{任意唯一值}" />即可解决索引问题,无需维护索引的连续性,使用时间戳代替自增索引作为每行的唯一索引值,删除行后也不会影响绑定逻辑
完整实现代码
1. 模型定义
public class ApplicationUserViewModel { public string Email { get; set; } public string FirstName { get; set; } public string LastName { get; set; } } public class BatchUserRegistrationViewModel { public List<ApplicationUserViewModel> Users { get; set; } }
2. Create 视图代码
@model NameSpace.Models.BatchUserRegistrationViewModel <form asp-action="RegisterManyUsers"> @if (Model.Users != null) { // 该部分用于ModelState校验不通过、POST请求回跳视图时,保留已提交的表单数据 for (int i = 0; i < Model.Users.Count; i++) { <div id="inputFormRow"> <div class="input-group mb-3"> <input type="hidden" name="Users.Index" value="@i" /> <input type="text" name="users[@i].Email"> <input type="text" name="users[@i].FirstName"> <input type="text" name="users[@i].LastName"> <div class="input-group-append"> <button id="removeRow" type="button"> (-) 移除行 </button> </div> </div> </div> } } else { // 该部分用于初始化空白表单 <div id="inputFormRow"> <div class="input-group mb-3"> <input type="hidden" name="Users.Index" value="0" /> <input type="text" name="users[0].Email"> <input type="text" name="users[0].FirstName"> <input type="text" name="users[0].LastName"> <div class="input-group-append"> <button id="removeRow" type="button"> (-) 移除行 </button> </div> </div> </div> } <div id="newRow"></div> <p> <button id="addRow" type="button"> (+) 新增行 </button> </p> <p> <button type="submit">(v) 注册用户</button> </p> </form>
3. 客户端脚本代码
<script> // 新增行 $("#addRow").click(function () { let ts = $.now(); var html = ''; html += '<div id="inputFormRow">'; html += ' <div class="input-group mb-3">'; html += ' <input type="hidden" name="Users.Index" value="' + ts + '" />'; html += ' <input type="text" name="users[' + ts + '].Email">'; html += ' <input type="text" name="users[' + ts + '].FirstName">'; html += ' <input type="text" name="users[' + ts + '].LastName">'; html += ' <div class="input-group-append">'; html += ' <button id="removeRow" type="button">'; html += ' (-) 移除行'; html += ' </button>'; html += ' </div>'; html += ' </div>'; html += '</div>'; $('#newRow').append(html); }); // 移除行 $(document).on('click', '#removeRow', function () { $(this).closest('#inputFormRow').remove(); }); </script>
4. 控制器POST方法代码
public async Task<IActionResult> RegisterManyUsers([Bind("Users")] BatchUserRegistrationViewModel BatchReg) { if (ModelState.IsValid) { if (BatchReg.Users != null) { List<ApplicationUser> dbUsers = new(); foreach (ApplicationUserViewModel user in BatchReg.Users) { dbUsers.Add(new ApplicationUser { Email = user.Email, FirstName = user.FirstName, LastName = user.LastName }); } db.AddRange(dbUsers); await db.SaveChangesAsync(); return RedirectToAction(nameof(Index)); } } return View(BatchReg); }
内容的提问来源于stack exchange,提问作者Stian
相关产品推荐
相关产品推荐

