ASP.NET Core 8 MVC中如何让ModelState忽略ScaffoldColumn特性?
问题描述
现有ViewModel类:
public class ModelTest { public ModelTest() { Name = "Jim"; } [Required] public string Name { get; set; } [ScaffoldColumn(false)] public string IgnoreMe { get; set; } }
对应的Action方法:
public IActionResult TestModel(ModelTest model) { var valid = ModelState.IsValid; return Json(ModelState); }
在ASP.NET MVC 5中,DataAnnotationsModelValidatorProvider执行验证时会忽略带有[ScaffoldColumn(false)]的字段,因此ModelState.IsValid返回true。但在ASP.NET Core 8 MVC中,ModelState.IsValid返回false,且提示IgnoreMe字段必填,错误信息如下:
{ "IgnoreMe": { "RawValue": null, "AttemptedValue": null, "Errors": [ { "Exception": null, "ErrorMessage": "The IgnoreMe field is required." } ], "ValidationState": 1, "IsContainerNode": false, "Children": null } }
需要修改该行为,让ModelState忽略带有[ScaffoldColumn(false)]的字段。
解决办法
方式一:替换为ASP.NET Core原生特性
ASP.NET Core官方推荐用[BindNever]标记无需绑定和验证的字段,直接替换原有的[ScaffoldColumn(false)]即可:
[BindNever] public string IgnoreMe { get; set; }
这个特性会让模型绑定器完全忽略该字段,不会触发任何验证,效果和MVC5中[ScaffoldColumn(false)]的验证行为一致。
方式二:自定义验证提供器,保留原有特性
如果不想改动现有代码的特性,可以自定义验证规则,让系统跳过带[ScaffoldColumn(false)]字段的验证:
- 创建自定义验证提供器类:
public class ScaffoldColumnIgnoringValidatorProvider : IModelValidatorProvider { public void CreateValidators(ModelValidatorProviderContext context) { var scaffoldAttr = context.ModelMetadata.Attributes.OfType<ScaffoldColumnAttribute>().FirstOrDefault(); if (scaffoldAttr != null && !scaffoldAttr.Scaffold) { // 清空该字段的所有验证器,跳过验证流程 context.Results.Clear(); } } }
- 在
Program.cs中注册该提供器(需放在添加MVC服务的代码之后):
builder.Services.AddControllersWithViews() .AddMvcOptions(options => { options.ModelValidatorProviders.Insert(0, new ScaffoldColumnIgnoringValidatorProvider()); });
注册完成后,所有带有[ScaffoldColumn(false)]的字段都会被跳过验证,和ASP.NET MVC 5的行为保持一致。
内容的提问来源于stack exchange,提问作者Craig
相关产品推荐
相关产品推荐

