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

如何填充CreateGroupViewModel?提交后ViewModel值为null问题解决

ASP.NET Core 提交时CreateGroupViewModel属性为null的解决方法

问题根源

  • 页面存在两个独立的<form>标签,订阅日期输入框在第一个表单,提交按钮在第二个表单,导致订阅日期数据无法随提交请求发送
  • 使用foreach遍历Department.Persons,生成的表单控件缺少索引标识,ASP.NET Core模型绑定无法识别集合元素
  • DayGroup对象仅在第一个表单中初始化,但未包含在提交的表单内,无法被绑定
  • 复杂对象(如AppUser、Department)没有对应的表单字段,模型绑定无法自动填充完整对象(仅能绑定简单类型或带索引的集合)

解决方案

1. 合并表单,统一提交范围

将所有需要提交的输入控件放到同一个<form>内,确保提交时能携带所有数据:

修改后的Create.cshtml:

@using QLAnCaWeb.ViewModels
@model CreateGroupViewModel
<div class="container mb-3">
    <div class="row pt-4">
        <div class="col-6">
            <h2 class="text-primary">
                ĐĂNG KÝ ĂN CA CHO TẬP THỂ
            </h2>
            <h3>
                HỌ TÊN: @Model.AppUser.Name
            </h3>
            <h3>
                PHÒNG BAN: @Model.Department.DepartmentName
            </h3>
        </div>
    </div>
</div>

<!-- 合并为单个表单 -->
<form method="post" asp-action="Create" class="row g-3">
    <!-- 订阅日期输入区域 -->
    <div class="row g-3 align-items-center mb-3">
        <div class="col-auto">
            <label for="SubDate" class="col-form-label">NGÀY ĐĂNG KÝ: </label>
        </div>
        <div class="col-auto">
            <input type="date" id="SubDate" asp-for="@Model.DayGroup.SubcriptionDate" class="form-control" />
            <span asp-validation-for="@Model.DayGroup.SubcriptionDate" class="text-dark"></span>
        </div>
    </div>

    <div class="mb-3 row">
        <div class="col-sm-3">
            <input type="text" readonly class="form-control-plaintext" value="DS HỌ TÊN" />
        </div>
        <div class="col">
            <input type="text" readonly class="form-control-plaintext" value="CA 1" />
        </div>
        <div class="col">
            <input type="text" readonly class="form-control-plaintext" value="CA 2" />
        </div>
        <div class="col">
            <input type="text" readonly class="form-control-plaintext" value="CA 3" />
        </div>
    </div>

    <!-- 用for循环代替foreach,添加索引支持集合绑定 -->
    @for (int i = 0; i < Model.Department.Persons.Count; i++)
    {
        <div class="row">
            <div class="col">
                <input type="text" readonly class="form-control-plaintext" value="@Model.Department.Persons[i].Name">
                <!-- 添加隐藏字段传递Person的ID,供后端识别对应实体 -->
                <input type="hidden" asp-for="@Model.Department.Persons[i].Id" />
            </div>
            <div class="col">
                <input class="form-control" type="number" asp-for="@Model.Department.Persons[i].Set1" />
                <span asp-validation-for="@Model.Department.Persons[i].Set1" class="text-dark"></span>
            </div>
            <div class="col">
                <input class="form-control" type="number" asp-for="@Model.Department.Persons[i].Set2" />
                <span asp-validation-for="@Model.Department.Persons[i].Set2" class="text-dark"></span>
            </div>
            <div class="col">
                <input class="form-control" type="number" asp-for="@Model.Department.Persons[i].Set3" />
                <span asp-validation-for="@Model.Department.Persons[i].Set3" class="text-dark"></span>
            </div>
        </div>
    }

    <div class="row g-3 align-items-center">
        <div class="col-auto">
            <button type="submit" class="btn btn-primary">Submit</button>
        </div>
        <div class="col-auto">
            <a class="btn btn-danger" asp-controller="Home" asp-action="Index">Cancel</a>
        </div>
    </div>
</form>

2. 提前初始化ViewModel中的DayGroup

在GET方法中提前初始化DayGroup,避免在视图中手动创建:

[HttpGet]
public async Task<IActionResult> Create() 
{
    var userId = _contextAccessor.HttpContext.User.FindFirstValue(ClaimTypes.NameIdentifier);
    var appUser = await _appUserRepository.GetByIdAsync(userId);
    var department = await _groupRepository.GetDepartmentByUserAsync(appUser);
    var createGroupViewModel = new CreateGroupViewModel()
    {
        AppUserId = userId,
        AppUser = appUser,
        Department = department,
        DayGroup = new DayGroup() // 提前初始化DayGroup
    };
    createGroupViewModel.Department.Persons = await _groupRepository.GetPeopleByDepartmentAsync(department);
    return View(createGroupViewModel);
}

3. 优化POST方法逻辑

复杂对象(如AppUser、Department)不要依赖表单绑定,而是通过ID从数据库重新获取,仅处理表单提交的可编辑数据:

[HttpPost]
public async Task<IActionResult> Create(CreateGroupViewModel model)
{
    if (!ModelState.IsValid)
    {
        // 验证失败时重新加载基础数据并返回视图
        model.AppUserId = _contextAccessor.HttpContext.User.FindFirstValue(ClaimTypes.NameIdentifier);
        model.AppUser = await _appUserRepository.GetByIdAsync(model.AppUserId);
        model.Department = await _groupRepository.GetDepartmentByUserAsync(model.AppUser);
        model.Department.Persons = await _groupRepository.GetPeopleByDepartmentAsync(model.Department);
        return View(model);
    }

    // 处理绑定成功的数据:model.DayGroup.SubcriptionDate 和 model.Department.Persons的Set字段已填充
    model.AppUserId = _contextAccessor.HttpContext.User.FindFirstValue(ClaimTypes.NameIdentifier);
    model.AppUser = await _appUserRepository.GetByIdAsync(model.AppUserId);
    model.Department = await _groupRepository.GetDepartmentByUserAsync(model.AppUser);
    
    // 后续业务逻辑
    return RedirectToAction(nameof(Index));
}

4. 验证绑定效果

在POST方法开头添加断点或日志,检查model.DayGroup.SubcriptionDate和model.Department.Persons的属性是否已正确填充。

内容的提问来源于stack exchange,提问作者Trung Đặng Đức

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.20 18:34:51