如何在ASP.NET MVC中实现DataTable数据新增并关联数据库
问题描述
我是ASP.NET MVC初学者,目前仅掌握在前端DataTable中动态添加行的操作,希望将该DataTable与数据库进行关联,但不知如何实现。我已创建好控制器、模型及数据类,完成了Delete、Edit、Index方法,仅需完善Create方法即可完成整个项目。
前端代码
var table = null; var arrData = []; var arrDataPG = []; arrData.push({ STT: 1, id: 1, product_type: "", condition1: "", }); $(document).ready(function () { InitTable(); }); function InitTable() { if (table !== null && table !== undefined) { table.destroy(); } table = $('#tableh').DataTable({ data: arrData, "columns": [ { "width": "25px" }, { "width": "300px" }, { "width": "300px" }, { "width": "25px" }, ], columnDefs: [ { title: "STT", targets: 0, data: null, render: function (data, type, row, meta) { return (meta.row + meta.settings._iDisplayStart + 1); }, }, { title: "Loại sản phẩm*", targets: 1, data: null, render: function (data, type, row, meta) { return '<textarea style="width: 300px;" id="product_type' + data.id + '" type="text" onchange="ChangeProductType(\'' + data.id + '\',this)" name="' + data.id + '" value="' + data.product_type + '">' + data.product_type + '</textarea>'; } }, { title: "Điều kiện*", targets: 2, data: null, render: function (data, type, row, meta) { return '<textarea style="width: 300px;" id="condition1' + data.id + '" type="text" onchange="ChangeCondition1(\'' + data.id + '\',this)" name="' + data.id + '" value="' + data.condition1 + '">' + data.condition1 + '</textarea>'; } }, { title: "", targets: 3, data: null, className: "dt-center", width: "70", render: function (data, type, row, meta) { return '<div class="btn btn-danger removePG" style="cursor: pointer;font-size:25px;" ><i class="fa-solid fa-trash"></i></div>'; } }, ], }); table.columns.adjust().draw(); } $('#addRow').on('click', function () { console.log(arrData.length); var ida = arrData.length > 0 ? arrData[0].id : 1; for (var i = 0; i < arrData.length; i++) { if (arrData[i].id > ida) { ida = arrData[i].id; } }; arrData.push({ STT: ida + 1, id: ida + 1, product_type: "", condition1: "", }); if (table != null) { table.clear(); table.rows.add(arrData).draw(); } }); $('#tableh').on('click', '.removePG', function () { var tableq = $('#tableh').DataTable(); var rowData = tableq.row($(this).parents('tr')).data(); removePG(rowData.id); tableq.row($(this).parents('tr')).remove().draw(); }); function removePG(idc) { let id = parseInt(idc); if (arrData !== undefined) { arrData = arrData.filter(item => item.id !== id); } } // 同步输入框内容到数组 function ChangeProductType(id, element) { var item = arrData.find(x => x.id == parseInt(id)); if(item) { item.product_type = element.value; } } function ChangeCondition1(id, element) { var item = arrData.find(x => x.id == parseInt(id)); if(item) { item.condition1 = element.value; } }
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script> <link rel="stylesheet"type="text/css"href="https://cdn.datatables.net/1.12.1/css/jquery.dataTables.min.css"> <table id="tableh" class="cell-border hover" style="width:100%"></table> <button style="width: 86px;" id="addRow" class="btn btn-success add">Addrow<i class="fa fa-plus" aria-hidden="true"></i></button> <!-- 新增提交按钮 --> <button style="width: 100px;" id="submitBtn" class="btn btn-primary">提交数据</button> <script src="https://code.jquery.com/jquery-3.5.1.js"></script> <script type="text/javascript" charset="utf8" src="https://cdn.datatables.net/1.12.1/js/jquery.dataTables.js"></script> <script src="https://kit.fontawesome.com/60bf89e922.js" crossorigin="anonymous"></script> <!-- 添加防伪造令牌 --> @Html.AntiForgeryToken() <!-- 批量提交AJAX逻辑 --> <script> $('#submitBtn').on('click', function() { // 过滤掉未填写产品类型的无效行 var submitData = arrData.filter(item => item.product_type.trim() !== ''); if(submitData.length === 0) { alert('至少要填写一行有效数据'); return; } $.ajax({ url: '/Firstrow/CreateMultiple', type: 'POST', contentType: 'application/json', data: JSON.stringify(submitData), headers: { 'RequestVerificationToken': $('input[name="__RequestVerificationToken"]').val() }, success: function(response) { if(response.success) { alert('提交成功'); window.location.href = '/Firstrow/Index'; } else { alert('提交失败:' + response.message); } }, error: function() { alert('服务器错误'); } }); }); </script>
控制器代码
using Microsoft.AspNetCore.Mvc; using WebApplication1.Data; using WebApplication1.Models; namespace WebApplication1.Controllers { public class FirstrowController : Controller { private readonly ApplicationDbContext _db; public FirstrowController(ApplicationDbContext db) { _db = db; } public IActionResult Index() { IEnumerable<Firstrow> objFirstrowList = _db.Firstrow; return View(objFirstrowList); } //Get public IActionResult Create() { return View(); } //POST 单行创建(保留原方法,按需使用) [HttpPost] [ValidateAntiForgeryToken] public IActionResult Create(Firstrow obj) { if (obj.product_type == obj.condition1.ToString()) { ModelState.AddModelError("name", "Nhập thiếu kìa fen"); } if (ModelState.IsValid) { _db.Firstrow.Add(obj); _db.SaveChanges(); return RedirectToAction("Index"); } return View(obj); } //POST 批量创建新方法 [HttpPost] [ValidateAntiForgeryToken] public IActionResult CreateMultiple([FromBody] List<Firstrow> rows) { if(rows == null || rows.Count == 0) { return Json(new { success = false, message = "没有提交任何数据" }); } foreach(var row in rows) { if(string.IsNullOrWhiteSpace(row.product_type)) { ModelState.AddModelError("", $"第{row.id}行的产品类型不能为空"); } } if(ModelState.IsValid) { _db.Firstrow.AddRange(rows); _db.SaveChanges(); return Json(new { success = true }); } // 收集所有错误信息返回前端 var errors = ModelState.Values.SelectMany(v => v.Errors).Select(e => e.ErrorMessage); return Json(new { success = false, message = string.Join("; ", errors) }); } //Get public IActionResult Edit(int? id) { if (id == null || id == 0) { return NotFound(); } var FirstrowFromDb = _db.Firstrow.Find(id); if (FirstrowFromDb == null) { return NotFound(); } return View(FirstrowFromDb); } //POST [HttpPost] [ValidateAntiForgeryToken] public IActionResult Edit(Firstrow obj) { if (obj.product_type == obj.condition1.ToString()) { ModelState.AddModelError("name", "Nhập thiếu kìa fen"); } if (ModelState.IsValid) { _db.Firstrow.Update(obj); _db.SaveChanges(); return RedirectToAction("Index"); } return View(obj); } //Get public IActionResult Delete(int? id) { if (id == null || id == 0) { return NotFound(); } var FirstrowFromDb = _db.Firstrow.Find(id); if (FirstrowFromDb == null) { return NotFound(); } return View(FirstrowFromDb); } //POST [HttpPost,ActionName("Delete")] [ValidateAntiForgeryToken] public IActionResult DeletePOST(int? id) { var obj = _db.Firstrow.Find(id); if (obj == null) { return NotFound(); } _db.Firstrow.Remove(obj); _db.SaveChanges(); return RedirectToAction("Index"); } } }
模型代码
using System.ComponentModel.DataAnnotations; namespace WebApplication1.Models { public class Firstrow { [Key] public int id { get; set; } [Required] public string product_type { get; set; } public string condition1 { get; set; } } }
实现说明
前端调整:
- 补充输入框内容同步方法,确保用户输入实时更新到
arrData数组 - 修复删除行逻辑,保证数组与DataTable数据完全同步
- 新增批量提交按钮和AJAX逻辑,过滤无效数据后发送到后端
- 添加防伪造令牌,符合ASP.NET MVC的安全验证要求
- 补充输入框内容同步方法,确保用户输入实时更新到
后端调整:
- 新增
CreateMultiple方法,接收前端传来的多行数据列表 - 对批量数据进行必填字段验证,返回明确的错误提示
- 使用
AddRange批量插入数据,提升数据库操作效率 - 返回JSON格式结果,方便前端处理提交状态
- 新增
注意事项:
- 模型的
id为自增主键,EF Core会自动生成新ID,前端的id仅用于行标识,不影响数据库存储 - 确保
ApplicationDbContext已正确配置数据库连接字符串 - 可根据业务需求调整验证规则和提示文案
- 模型的
内容的提问来源于stack exchange,提问作者quanhprx
相关产品推荐
相关产品推荐

