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

.NET Core中带AllowNull导航属性的模型提交时ModelState无效问题

EF脚手架生成的分类/产品控制器创建/编辑时ModelState校验失败问题

分类(Categories)与产品(Product)为一对多关系,使用Entity Framework脚手架生成默认控制器和视图创建/编辑分类时,ModelState始终失效,产品控制器也存在同样问题。表单仅提交CategoryName和url两个字段,但ModelState会检查Products导航属性,报错:"The Products field is required."

模型代码

public class Product
{
    [Key]
    public int ProductId { get; set; }

    // Foreign Key
    [ForeignKey("CategoryId")]
    public int CategoryID { get; set; }

    public Categories Category { get; set; }

    public string Name { get; set; }
    public string Description { get; set; }
    public string url { get; set; }
    public decimal Price { get; set; }
}

public class Categories
{
    [Key]
    public int CategoryID { get; set; }
    public string CategoryName { get; set; }
    public string url { get; set; }

    // Navigation Property for Products (optional but recommended)
    [AllowNull]
    public ICollection<Product> Products { get; set; }
}
// In your Models folder (or create a ViewModels folder)
public class ProductsCategoriesViewModel
{
    public List<Categories> Categories { get; set; }
    public List<Product> Products { get; set; }
}

默认Create控制器代码

[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> Create([Bind("CategoryID,CategoryName,url")] Categories categories)
{
    if (ModelState.IsValid)
    {
        _context.Add(categories);
        await _context.SaveChangesAsync();
        return RedirectToAction(nameof(Index));
    }
    return View(categories);
}

Create.cshtml视图代码

@model MyKartV2.Models.Categories

@{
    ViewData["Title"] = "Create";
}

<h1>Create</h1>

<h4>Categories</h4>
<hr />
<div class="row">
    <div class="col-md-4">
        <form asp-action="Create">
            <div asp-validation-summary="ModelOnly" class="text-danger"></div>
            <div class="form-group">
                <label asp-for="CategoryName" class="control-label"></label>
                <input asp-for="CategoryName" class="form-control" />
                <span asp-validation-for="CategoryName" class="text-danger"></span>
            </div>
            <div class="form-group">
                <label asp-for="url" class="control-label"></label>
                <input asp-for="url" class="form-control" />
                <span asp-validation-for="url" class="text-danger"></span>
            </div>
            <div class="form-group">
                <input type="submit" value="Create" class="btn btn-primary" />
            </div>
        </form>
    </div>
</div>

<div>
    <a asp-action="Index">Back to List</a>
</div>

@section Scripts {
    @{await Html.RenderPartialAsync("_ValidationScriptsPartial");}
}

补充说明

表单仅提交两个字段,但ModelState仍为导航属性Products添加校验条目,导致ModelState无效,错误信息为*"The Products field is required."*


解决思路及方案

方案1:给导航属性添加忽略绑定特性

在Categories类的Products属性上添加[BindNever],告诉模型绑定器忽略该属性,不参与校验:

[BindNever]
public ICollection<Product> Products { get; set; }

方案2:初始化导航属性集合

在Categories类中给Products属性赋默认空集合,避免属性为null触发校验:

public ICollection<Product> Products { get; set; } = new List<Product>();

方案3:使用ViewModel接收表单数据

创建仅包含表单所需字段的ViewModel,避免实体类的导航属性干扰校验:

public class CategoryCreateViewModel
{
    public string CategoryName { get; set; }
    public string url { get; set; }
}

修改控制器接收ViewModel并映射到实体:

[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> Create(CategoryCreateViewModel model)
{
    if (ModelState.IsValid)
    {
        var category = new Categories
        {
            CategoryName = model.CategoryName,
            url = model.url
        };
        _context.Add(category);
        await _context.SaveChangesAsync();
        return RedirectToAction(nameof(Index));
    }
    return View(new Categories { CategoryName = model.CategoryName, url = model.url });
}

同时将视图的@model改为MyKartV2.Models.CategoryCreateViewModel。

方案4:手动移除ModelState中的错误

在控制器中手动移除Products属性的校验错误:

[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> Create([Bind("CategoryID,CategoryName,url")] Categories categories)
{
    ModelState.Remove("Products");
    if (ModelState.IsValid)
    {
        _context.Add(categories);
        await _context.SaveChangesAsync();
        return RedirectToAction(nameof(Index));
    }
    return View(categories);
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.22 14:57:33