ASP.NET MVC加[Required]注解后访问Razor视图报SqlNullValueException原因询问
错误根因说明
这个异常的触发和表单提交逻辑无关,完全是数据查询阶段的EF Core实体映射规则与现有数据库数据不匹配导致的,具体逻辑如下:
[Required]数据注解不仅会作用于表单验证,还会被EF Core识别,自动将实体属性对应的数据库字段设为NOT NULL非空约束。- 你在添加
[Required]注解前,Name字段在数据库中是允许空值的,库中已经存在Name为NULL的Category记录。 - 访问Index页面时,控制器会从数据库查询全量
Category列表返回给视图,EF Core在将查询结果映射到实体对象时,尝试把数据库返回的NULL值赋值给被[Required]标记为非空的Name属性,就会抛出SqlNullValueException。 - 你看到错误指向
@if(Model.Count() > 0)这一行,是因为这行代码触发了EF Core查询结果的枚举操作,才把底层映射的异常抛了出来,错误本身和这行代码的逻辑无关。
为什么只有访问页面报错、提交表单不报错
- 提交表单时触发的是模型验证逻辑:如果输入的
Name为空,只会返回表单验证错误,不会走到查询历史数据的步骤;如果输入的Name有值,自然不会触发任何异常。 - 删除
[Required]注解后,EF Core认为Name是可空字符串,允许赋值为NULL,映射时就不会抛出异常,但也失去了对应的非空约束能力。
修复方案
- 先清理数据库中现有
Name为NULL的Category记录,给所有空记录补全合法的Name值 - 如果使用EF Core迁移管理表结构,添加
[Required]后需要执行迁移操作,将数据库中Name字段的约束同步为NOT NULL,避免后续再写入空值 - 如果业务允许
Name为空,可以将属性声明修改为public string? Name { get; set; }显式标记为可空字符串,同时保留自定义验证逻辑即可。
内容的提问来源于stack exchange,提问作者Emanuel Boștină
相关产品推荐
相关产品推荐

