[英]Correct way to disable model validation in ASP.Net Core 2 MVC
使用擴展方法設置 MVC
services.AddMvc()
然后在 controller 中,這也可能適用於 GET,使用正文中提供的參數為 POST 操作創建一個方法,例如
[HttpPost("save")]
public Entity Save([FromBody]Entity someEntity)
當動作被調用時,MVC 管道將調用 ParameterBinder,后者又調用DefaultObjectValidator
。 我不想要驗證(一方面它很慢,但更重要的是在復雜的循環圖上循環),但似乎關閉管道中驗證的唯一方法是這樣的:
public class NonValidatingValidator : IObjectModelValidator
{
public void Validate(ActionContext actionContext, ValidationStateDictionary validationState, string prefix, object model)
{
}
}
在 StartUp/ConfigureServices 中:
var validator = services.FirstOrDefault(s => s.ServiceType == typeof(IObjectModelValidator));
if (validator != null)
{
services.Remove(validator);
services.Add(new ServiceDescriptor(typeof(IObjectModelValidator), _ => new NonValidatingValidator(), ServiceLifetime.Singleton));
}
這看起來像一把大錘。 我環顧四周,找不到替代方案,還嘗試刪除DataAnnotationModelValidator
但沒有成功,所以想知道是否有更好/正確的方法來關閉驗證?
services.Configure<ApiBehaviorOptions>(options =>
{
options.SuppressModelStateInvalidFilter = true;
});
應該禁用自動模型狀態驗證。
使用這個擴展方法:
public static IServiceCollection DisableDefaultModelValidation(this IServiceCollection services)
{
ServiceDescriptor serviceDescriptor = services.FirstOrDefault<ServiceDescriptor>((Func<ServiceDescriptor, bool>) (s => s.ServiceType == typeof (IObjectModelValidator)));
if (serviceDescriptor != null)
{
services.Remove(serviceDescriptor);
services.Add(new ServiceDescriptor(typeof (IObjectModelValidator), (Func<IServiceProvider, object>) (_ => (object) new EmptyModelValidator()), ServiceLifetime.Singleton));
}
return services;
}
public class EmptyModelValidator : IObjectModelValidator
{
public void Validate(ActionContext actionContext, ValidationStateDictionary validationState, string prefix, object model)
{
}
}
用法:
public void ConfigureServices(IServiceCollection services)
{
services.DisableDefaultModelValidation();
}
從aspnet core 3.1
,這是禁用模型驗證的方法,如文檔中所示:
首先創建這個 NullValidator 類:
public class NullObjectModelValidator : IObjectModelValidator
{
public void Validate(ActionContext actionContext,
ValidationStateDictionary validationState, string prefix, object model)
{
}
}
然后用它代替真正的模型驗證器:
services.AddSingleton<IObjectModelValidator, NullObjectModelValidator>();
請注意,這只會禁用模型驗證,您仍然會收到模型綁定錯誤。
.AddMvc()
擴展方法有一個重載,你可以在其中配置很多東西。 其中之一是ModelValidatorProviders
的列表。
如果您清除此列表,例如:
services.AddMvc(options => options.ModelValidatorProviders.Clear());
不應再進行驗證。
創建空模型驗證器類。
public class EmptyModelValidator : IObjectModelValidator {
public void Validate(
ActionContext actionContext,
ValidationStateDictionary validationState,
string prefix,
object model) {
}
}
在配置服務方法中將 DefaultModelValidator 替換為 EmptyModelValidator。
services.Replace(
new ServiceDescriptor(typeof(IObjectModelValidator),
typeof(EmptyModelValidator),
ServiceLifetime.Singleton)
);
EmptyModelValidator 不驗證模型,因此 ModelState.IsValid 總是返回false
。
您應該考慮使用ValidateNeverAttribute ,它幾乎沒有記錄並且被微軟很好地隱藏起來。
[ValidateNever]
public class Entity
{
....
}
這使您可以細粒度地控制哪些實體要驗證,哪些不驗證。
要關閉所有繼承 class 的驗證:
var mvc = services.AddMvc(options =>
{
options.ModelMetadataDetailsProviders.Add(new SuppressChildValidationMetadataProvider(typeof(VMClass)));
}); // to avoid validation of the complete world by following VMClass refs
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.