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

ASP.NET Core 8 MVC中Create方法ModelState无效:conturi_sintetice必填错误

ASP.NET Core 8 MVC Create方法ModelState无效:conturi_sintetice必填字段问题

我开发了一个ASP.NET Core 8 MVC应用,执行Create方法时出现ModelState无效的问题,错误提示为“conturi_sintetice是必填字段”。相关代码如下:

实体类定义

public class rjd
{
    [Key]
    public int id_registru_jurnal { get; set; }

    public DateTime data { get; set; }

    public string nr_document { get; set; }

    [ForeignKey("conturi_sintetice")]
    public int id_CS_debitor { get; set; }       
 
    public decimal debit { get; set; }

    public decimal credit { get; set; }

    public conturi_sintetice conturi_sintetice { get; set; }            
}

public class conturi_sintetice
{     
    [Key]
    public int id_cont_sintetic { get; set; }

    public string explicatie_nr_cont_sintetic { get; set; }
}

控制器Create方法

public async Task<IActionResult> Create([Bind("id_registru_jurnal,data,nr_document,id_CS_debitor,debit,credit")] rjd rjd)
{
    if (ModelState.IsValid)
    {       
        _context.Add(rjd);
        await _context.SaveChangesAsync();
        return RedirectToAction(nameof(Index));
    }

    ViewData["id_CS_debitor"] = new SelectList(_context.Set<conturi_sintetice>(), "id_cont_sintetic", "id_cont_sintetic", rjd.id_CS_debitor);
    return View(rjd);
}

视图Create表单

<form asp-action="Create">
    <div asp-validation-summary="ModelOnly" class="text-danger"></div>

  ......
  
 <div class="form-group">
    <label asp-for="id_CS_debitor" class="control-label"></label>
    <select asp-for="id_CS_debitor" class="form-control" asp-items="ViewBag.id_CS_debitor"></select>
</div>
 
 .......

    <div class="form-group">
        <input type="submit" value="Create" class="btn btn-primary" />
    </div>
</form>

问题原因

问题出在EF Core的模型验证逻辑:rjd类中的conturi_sintetice是引用类型的导航属性,在C# 8及以上版本的非空引用类型规则下,该属性默认会被模型绑定器标记为必填项。但Create操作中我们只提交了外键字段id_CS_debitor,并没有传递conturi_sintetice实体本身,因此ModelState验证失败,抛出必填字段错误。

解决方案

方案一:将导航属性改为可空类型

修改rjd类中的导航属性,添加可空运算符?,明确声明该属性允许为null:

public conturi_sintetice? conturi_sintetice { get; set; }

这是最符合C#规范的做法,能从根源上让模型验证正确识别该属性的可选性。

方案二:用[BindNever]标记导航属性

在导航属性上添加[BindNever]特性,让模型绑定器忽略该属性的验证:

[BindNever]
public conturi_sintetice conturi_sintetice { get; set; }

这样模型绑定过程中不会检查conturi_sintetice的值,自然不会触发必填验证错误。

方案三:手动移除ModelState中的验证错误

在控制器Create方法中,判断ModelState有效性之前,手动移除conturi_sintetice对应的验证错误:

public async Task<IActionResult> Create([Bind("id_registru_jurnal,data,nr_document,id_CS_debitor,debit,credit")] rjd rjd)
{
    ModelState.Remove("conturi_sintetice");

    if (ModelState.IsValid)
    {       
        _context.Add(rjd);
        await _context.SaveChangesAsync();
        return RedirectToAction(nameof(Index));
    }

    ViewData["id_CS_debitor"] = new SelectList(_context.Set<conturi_sintetice>(), "id_cont_sintetic", "id_cont_sintetic", rjd.id_CS_debitor);
    return View(rjd);
}

该方案适合无法修改实体类的场景,通过临时跳过指定属性的验证来解决问题。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.16 02:05:21