MVC5中如何将局部视图下拉框值传递给父视图模型?
问题分析与解决方案
你遇到的问题核心是表单提交时,局部视图里的下拉框值没有被包含在提交的表单数据中,这是因为HTML表单只会提交带有name属性的元素值,而你的下拉框目前只有id,没有设置name属性;另外,<option>标签用id存储选项值也是错误的,应该用value属性来定义选项的提交值。
先看你的现有代码示意:
原局部视图代码
@model IEnumerable<ArdentTestv6.Repositories.SelectProjectTypes_Result> <div> <select id="SelectProjectType" class="alert-danger" title="Please Select"> <option id="0"></option> @foreach(var item in Model) { <option id="@item.TypeID"> @item.TypeName </option> } </select> </div>
原父视图关键部分
@model ArdentTestv6.Repositories.ProjectList @{ ViewBag.Title = "Create"; } <h2>Create</h2> @using (Html.BeginForm()) { <!-- 其他表单元素 --> <div id="projType" class="form-group"> @Html.Label("Project Type", htmlAttributes: new { @class = "control-label col-md-2" }) <div class="col-md-10"> @{Html.RenderAction("_ListProjectTypes", "ProjectTypes", new { htmlAttributes = new { @class = "form-control" } });} </div> </div> <!-- 其他表单元素 --> }
解决步骤
1. 给父视图模型添加对应字段
首先,你的ProjectList模型需要新增一个用来接收下拉框选中值的属性,比如:
public class ProjectList { // 保留你原有的其他属性... public int? ProjectTypeId { get; set; } // 添加这个字段,存储选中的项目类型ID }
2. 修改局部视图,修复表单提交必要属性
局部视图需要调整两点:
- 给
<select>添加name属性,值要和父模型的字段名完全一致(这里是ProjectTypeId) - 将
<option>的id改为value,因为表单提交时会传递选中选项的value值
修改后的局部视图代码:
@model IEnumerable<ArdentTestv6.Repositories.SelectProjectTypes_Result> <div> <!-- 添加name属性,与父模型字段匹配 --> <select id="SelectProjectType" name="ProjectTypeId" class="alert-danger form-control" title="Please Select"> <!-- 空选项的value设为"",对应可空int类型 --> <option value="">-- Please Select --</option> @foreach(var item in Model) { <!-- 用value存储TypeID,替代原来的id --> <option value="@item.TypeID">@item.TypeName</option> } </select> </div>
3. (可选)用MVC强类型辅助方法优化局部视图
如果你想让代码更贴合MVC的强类型模式,可以让局部视图接收父模型的字段信息,或者传递name参数进去。比如修改父视图的RenderAction调用:
@{Html.RenderAction("_ListProjectTypes", "ProjectTypes", new { htmlAttributes = new { @class = "form-control" }, name = "ProjectTypeId" // 传递name参数给局部视图 });}
然后局部视图接收参数并使用Html.DropDownList辅助方法:
@model IEnumerable<ArdentTestv6.Repositories.SelectProjectTypes_Result> @{ var name = ViewData["name"] as string ?? "ProjectTypeId"; var htmlAttributes = ViewData["htmlAttributes"] as IDictionary<string, object> ?? new Dictionary<string, object>(); } <div> @Html.DropDownList(name, new SelectList(Model, "TypeID", "TypeName"), "-- Please Select --", htmlAttributes) </div>
这种方式会自动生成正确的name和value,代码也更简洁。
4. 控制器接收值
现在你的Create动作方法可以直接从模型中获取选中的ProjectTypeId:
[HttpPost] public ActionResult Create(ProjectList model) { if (ModelState.IsValid) { // model.ProjectTypeId 就是下拉框选中的项目类型ID // 执行你的保存逻辑... return RedirectToAction("Index"); } // 验证失败时返回视图 return View(model); }
这样修改后,表单提交时下拉框的选中值就会被正确绑定到父视图模型的ProjectTypeId字段,也会出现在FormCollection中了。
内容的提问来源于stack exchange,提问作者Allen Jones
相关产品推荐
相关产品推荐

