簡體   English   中英

在 ASP.Net Core 2 MVC 中禁用 model 驗證的正確方法

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM