ASP.NET MVC中如何将IEnumerable<Dairy_XL>从视图传递到控制器
解决ASP.NET MVC中传递IEnumerable模型到控制器为空的问题
你遇到的问题是因为使用@Html.ActionLink传递复杂集合模型时,生成的是GET请求,而GET请求无法通过URL正确传递复杂对象(比如List<Dairy_XL>),导致模型绑定器无法解析参数,所以xl_model为空。下面是两种可行的解决方案:
方案一:使用表单POST提交(传统方式)
步骤1:修改视图,用表单和隐藏字段传递模型
因为你的模型是IEnumerable<Dairy_XL>,需要为每个元素的属性生成命名正确的隐藏字段,这样ASP.NET MVC的模型绑定器才能识别集合。
@model IEnumerable<Javad_New.Models.Dairy_XL> <!-- 保留你的表格展示代码 --> <div class="container"> <div class="col-md-4"></div> <div class="col-md-4"> @using (Html.BeginForm("Import_Dairy_XL", "YourControllerName", FormMethod.Post)) { int itemIndex = 0; foreach (var dairyItem in Model) { <!-- 为每个属性生成隐藏字段,注意Name属性的格式:xl_model[索引].属性名 --> @Html.HiddenFor(m => dairyItem.No, new { Name = $"xl_model[{itemIndex}].No" }) @Html.HiddenFor(m => dairyItem.RegNo, new { Name = $"xl_model[{itemIndex}].RegNo" }) @Html.HiddenFor(m => dairyItem.NAAB_CODE, new { Name = $"xl_model[{itemIndex}].NAAB_CODE" }) @Html.HiddenFor(m => dairyItem.NAME, new { Name = $"xl_model[{itemIndex}].NAME" }) <!-- 依次添加Dairy_XL的所有其他属性,比如ICC、LNM...直到color_cap --> @Html.HiddenFor(m => dairyItem.color_cap, new { Name = $"xl_model[{itemIndex}].color_cap" }) itemIndex++; } <button type="submit" class="btn btn-primary">IMPORT</button> } </div> <div class="col-md-4"></div> </div>
步骤2:修改控制器方法,添加[HttpPost]标记
确保控制器方法接收POST请求:
[HttpPost] public ActionResult Import_Dairy_XL(List<Dairy_XL> xl_model) { // 空值判断避免空引用异常 ViewBag.test = xl_model?.Count ?? 0; return View(); }
简化技巧:使用EditorTemplate
如果手动写所有隐藏字段太麻烦,可以创建一个编辑器模板:
- 在
Views/Shared/EditorTemplates文件夹下创建Dairy_XL.cshtml(如果文件夹不存在就新建):
@model Javad_New.Models.Dairy_XL @Html.HiddenFor(m => m.No) @Html.HiddenFor(m => m.RegNo) @Html.HiddenFor(m => m.NAAB_CODE) <!-- 依次添加所有其他属性 --> @Html.HiddenFor(m => m.color_cap)
- 然后在主视图中用
EditorFor替代手动遍历:
@using (Html.BeginForm("Import_Dairy_XL", "YourControllerName", FormMethod.Post)) { @Html.EditorFor(m => m, new { htmlAttributes = new { Name = "xl_model" } }) <button type="submit" class="btn btn-primary">IMPORT</button> }
编辑器模板会自动为集合中的每个元素生成正确命名的隐藏字段,无需手动维护索引。
方案二:使用Ajax POST传递JSON(更简洁高效)
如果数据量较大或者想避免页面刷新,用Ajax传递JSON是更好的选择:
步骤1:修改视图,添加按钮和Ajax脚本
@model IEnumerable<Javad_New.Models.Dairy_XL> <!-- 保留你的表格展示代码 --> <div class="container"> <div class="col-md-4"></div> <div class="col-md-4"> <button id="importBtn" class="btn btn-primary">IMPORT</button> </div> <div class="col-md-4"></div> </div> @section Scripts { <script src="https://code.jquery.com/jquery-3.6.0.min.js"></script> <script> $(document).ready(function() { $('#importBtn').click(function(e) { e.preventDefault(); // 将服务器端模型序列化为JSON(ASP.NET Core用Json.Serialize,MVC经典版用Json.Encode) var dairyData = @Html.Raw(Json.Serialize(Model)); $.ajax({ url: '@Url.Action("Import_Dairy_XL", "YourControllerName")', type: 'POST', contentType: 'application/json; charset=utf-8', data: JSON.stringify(dairyData), success: function(response) { // 导入成功后的逻辑,比如跳转到结果页或提示用户 alert(`成功导入 ${response.test} 条数据`); // 或者替换当前视图内容 // $('body').html(response); }, error: function(xhr, status, error) { alert('导入失败:' + error); } }); }); }); </script> }
步骤2:修改控制器方法,支持JSON绑定
[HttpPost] public ActionResult Import_Dairy_XL([FromBody] List<Dairy_XL> xl_model) { ViewBag.test = xl_model?.Count ?? 0; // 如果是Ajax请求,可以返回Json结果 return Json(new { test = ViewBag.test }); // 或者继续返回视图 // return View(); }
关键原因解释
@Html.ActionLink生成的是GET请求,GET请求的参数通过URL查询字符串传递,而复杂集合对象无法通过URL参数被模型绑定器正确解析。POST请求则可以将数据放在请求体中(无论是表单格式还是JSON),模型绑定器能正确识别并映射到List<Dairy_XL>参数。
内容的提问来源于stack exchange,提问作者Rouzbeh Zarandi
相关产品推荐
相关产品推荐

