You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在.NET Core MVC中将表单绑定到父子结构的ViewModel

你现有的cshtml模板核心逻辑是符合ASP.NET MVC的集合绑定规则的,只要配套对应的ViewModel定义和控制器接收逻辑就可以正常运行,以下是完整的最优实现方案:

1 视图模板优化

你当前用for循环带索引渲染子项的写法是正确的,渲染出的input控件name属性会自动生成为PowerCurvePoints[0].Bin的格式,刚好匹配模型绑定的规则,仅需要注意两个点:

  • GET请求渲染页面前,必须给父级ViewModel的PowerCurvePoints集合初始化25-30个空的子ViewModel实例,否则for循环不会执行,不会渲染出子项输入框
  • 可以将重复的子项渲染逻辑抽为局部视图,降低代码冗余,方便后续维护

抽局部视图的实现示例

新建_PowerCurvePointItem.cshtml局部视图:

@model PowerCurvePointViewModel
@{
    // 从视图数据获取当前子项的索引
    int index = (int)ViewData["ItemIndex"];
}
<div class="form-group">
    <label asp-for="Bin" class="control-label"></label>
    <input asp-for="Bin" name="PowerCurvePoints[@index].Bin" class="form-control" />
    <span asp-validation-for="Bin" class="text-danger"></span>
</div>
<div class="form-group">
    <label asp-for="WindSpeed" class="control-label"></label>
    <input asp-for="WindSpeed" name="PowerCurvePoints[@index].WindSpeed" class="form-control" />
    <span asp-validation-for="WindSpeed" class="text-danger"></span>
</div>
<div class="form-group">
    <label asp-for="ActivePower" class="control-label"></label>
    <input asp-for="ActivePower" name="PowerCurvePoints[@index].ActivePower" class="form-control" />
    <span asp-validation-for="ActivePower" class="text-danger"></span>
</div>

主页面的循环部分简化为:

@for (var i = 0; i < Model.PowerCurvePoints.Count; i++)
{
    @await Html.PartialAsync("_PowerCurvePointItem", Model.PowerCurvePoints[i], new ViewDataDictionary(ViewData) { {"ItemIndex", i} })
}

2 控制器绑定实现

首先定义和前端字段完全匹配的ViewModel结构:

// 子项ViewModel
public class PowerCurvePointViewModel
{
    public int Bin { get; set; }
    public decimal WindSpeed { get; set; }
    public decimal ActivePower { get; set; }
}

// 父级提交ViewModel
public class PowerCurveCreateViewModel
{
    public string Description { get; set; }
    // 必须用可索引的集合类型,比如List<T>,不要用IEnumerable<T>
    public List<PowerCurvePointViewModel> PowerCurvePoints { get; set; } = new List<PowerCurvePointViewModel>();
}

控制器的Post接收Action直接将父级ViewModel作为参数即可,模型绑定会自动填充所有字段:

[HttpPost]
public IActionResult Create(PowerCurveCreateViewModel model)
{
    if (ModelState.IsValid)
    {
        // 此处model.Description为提交的描述字段
        // model.PowerCurvePoints已经包含所有25-30条提交的子项数据
        // 执行业务保存逻辑即可
        return RedirectToAction("Index");
    }
    // 校验失败时回显数据
    return View(model);
}

常见问题排查

  • 若提交后PowerCurvePoints为空,先检查提交的表单字段name是否符合PowerCurvePoints[索引].属性名的格式
  • 不要用foreach循环渲染子项,不会生成带索引的name属性,会导致绑定失败
  • 若需要客户端校验,确保页面引入了jquery.validate.js和jquery.validate.unobtrusive.js两个脚本

内容的提问来源于stack exchange,提问作者Ross Halliday

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.07 02:12:02