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

ASP.NET Core 6表单提交时ContactViewModel传值为null的解决咨询

问题

在ASP.NET Core 6项目中,我创建了带验证特性的ContactViewModel类,又定义了包含该类及IEnumerable<Category>的MenuViewModel。在Index视图中以MenuViewModel为模型构建表单后,提交时控制器的MenuViewModel参数里的ContactViewModel属性始终为null,无法获取前端输入内容,该如何解决?

相关代码

ContactViewModel代码

public class ContactViewModel
{        
    [Required(ErrorMessage = "请输入您的姓名。")]
    public string Name { get; set; }
    [Required(ErrorMessage = "请输入您的邮箱。")]
    public string Email { get; set; }
    [Required(ErrorMessage = "请输入您的留言。")]
    public string Message { get; set; }
}
public class MenuViewModel
{
    public ContactViewModel ContactViewModel { get; set; }
    public IEnumerable<Category> Category { get; set; }
}

视图表单代码

@model project.Models.ViewModels.MenuViewModel
<form method="post" asp-action="ContactMe" asp-controller="Contact" id="contact-form">
  <div class="form-group col-md-6">
    <label>姓名</label>
    <input asp-for="ContactViewModel.Name" type="text" class="form-control" id="name">
    <span asp-validation-for="ContactViewModel.Name" class="text-danger"></span>
  </div>

  <div class="form-group col-md-6">
    <label>邮箱</label>
    <input asp-for="ContactViewModel.Email" type="text" class="form-control" id="Email">
    <span asp-validation-for="ContactViewModel.Email" class="text-danger"></span>
  </div>

  <div class="form-group col-md-6">
    <label>留言</label>
    <input asp-for="ContactViewModel.Message" type="text" class="form-control" id="Message">
    <span asp-validation-for="ContactViewModel.Message" class="text-danger"></span>
  </div>

  <input type="submit" id="submit" class="btn btn-primary px-5 py-2" value="发送">
</form>

控制器代码

[HttpPost]
public async Task<IActionResult> ContactMe(MenuViewModel menu)
{
    if(!ModelState.IsValid)
    {
        return NotFound();
    }

    // 写入数据库逻辑
}
解决方案

问题核心是模型绑定器无法为未初始化的引用类型属性赋值:MenuViewModel中的ContactViewModel是引用类型,默认值为null,绑定器无法直接给null对象的属性赋值。可通过以下两种方式解决:

方式一:在MenuViewModel中初始化ContactViewModel

修改MenuViewModel代码,直接在属性声明时实例化ContactViewModel:

public class MenuViewModel
{
    // 初始化嵌套的ContactViewModel实例
    public ContactViewModel ContactViewModel { get; set; } = new ContactViewModel();
    public IEnumerable<Category> Category { get; set; }
}

方式二:在控制器GET方法中实例化MenuViewModel

如果表单是通过GET方法返回的视图,需要在GET方法中创建MenuViewModel实例并初始化ContactViewModel:

[HttpGet]
public IActionResult Index()
{
    var menuViewModel = new MenuViewModel
    {
        ContactViewModel = new ContactViewModel(),
        // 按需初始化Category数据
        Category = _categoryService.GetAllCategories()
    };
    return View(menuViewModel);
}

额外优化点

  1. 移除表单中手动添加的name属性:asp-for标签助手会自动生成正确的name值(如ContactViewModel.Name),手动添加可能引发冲突,建议删除。
  2. 修正控制器错误返回逻辑:原代码返回NotFound()会丢失用户输入,应改为return View(menu),保留用户输入并显示验证错误信息。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.03 21:05:20