/// <summary> /// Adds Fluent Validation services to the specified /// <see cref="T:Microsoft.Extensions.DependencyInjection.IMvcBuilder" />. /// </summary> /// <returns> /// An <see cref="T:Microsoft.Extensions.DependencyInjection.IMvcCoreBuilder" /> that can be used to further configure the /// MVC services. /// </returns> public static IMvcCoreBuilder AddFluentValidation(this IMvcCoreBuilder mvcBuilder, Action <FluentValidationMvcConfiguration> configurationExpression = null) { var config = new FluentValidationMvcConfiguration(ValidatorOptions.Global); configurationExpression?.Invoke(config); RegisterServices(mvcBuilder.Services, config); mvcBuilder.AddMvcOptions(options => { // Check if the providers have already been added. // We shouldn't have to do this, but there's a bug in the ASP.NET Core integration // testing components that can cause Configureservices to be called multple times // meaning we end up with duplicates. if (!options.ModelMetadataDetailsProviders.Any(x => x is FluentValidationBindingMetadataProvider)) { options.ModelMetadataDetailsProviders.Add(new FluentValidationBindingMetadataProvider()); } if (!options.ModelValidatorProviders.Any(x => x is FluentValidationModelValidatorProvider)) { options.ModelValidatorProviders.Insert(0, new FluentValidationModelValidatorProvider(config.ImplicitlyValidateChildProperties)); } }); return(mvcBuilder); }
private static void RegisterServices(IServiceCollection services, FluentValidationMvcConfiguration config) { if (config.ValidatorFactory != null) { // Allow user to register their own IValidatorFactory instance, before falling back to try resolving by Type. var factory = config.ValidatorFactory; services.Add(ServiceDescriptor.Scoped(s => factory)); } else { services.Add(ServiceDescriptor.Scoped(typeof(IValidatorFactory), config.ValidatorFactoryType ?? typeof(ServiceProviderValidatorFactory))); } services.Add(ServiceDescriptor.Singleton <IObjectModelValidator, FluentValidationObjectModelValidator>(s => { var options = s.GetRequiredService <IOptions <MvcOptions> >().Value; var metadataProvider = s.GetRequiredService <IModelMetadataProvider>(); return(new FluentValidationObjectModelValidator(metadataProvider, options.ModelValidatorProviders)); })); if (config.ClientsideEnabled) { services.TryAddEnumerable(ServiceDescriptor.Transient <IConfigureOptions <MvcViewOptions>, FluentValidationViewOptionsSetup>(s => { return(new FluentValidationViewOptionsSetup(s.GetService <IValidatorFactory>(), config.ClientsideConfig)); })); } }
private static void RegisterServices(IServiceCollection services, FluentValidationMvcConfiguration config) { if (config.ValidatorFactory != null) { // Allow user to register their own IValidatorFactory instance, before falling back to try resolving by Type. var factory = config.ValidatorFactory; services.Add(ServiceDescriptor.Transient(s => factory)); } else { services.Add(ServiceDescriptor.Transient(typeof(IValidatorFactory), config.ValidatorFactoryType ?? typeof(ServiceProviderValidatorFactory))); } services.Add(ServiceDescriptor.Singleton <IObjectModelValidator, FluentValidationObjectModelValidator>(s => { var options = s.GetRequiredService <IOptions <MvcOptions> >().Value; var metadataProvider = s.GetRequiredService <IModelMetadataProvider>(); return(new FluentValidationObjectModelValidator(metadataProvider, options.ModelValidatorProviders, config.RunDefaultMvcValidationAfterFluentValidationExecutes)); })); if (config.ClientsideEnabled) { // Clientside validation requires access to the Httpcontext, but MVC's clientside API does not provide it, // so we need to inject the HttpContextAccessor instead. // This is not registered by default, so add it in if the user hasn't done so. services.TryAddSingleton <IHttpContextAccessor, HttpContextAccessor>(); services.TryAddEnumerable(ServiceDescriptor.Transient <IConfigureOptions <MvcViewOptions>, FluentValidationViewOptionsSetup>(s => { return(new FluentValidationViewOptionsSetup(config.ClientsideConfig, s.GetService <IHttpContextAccessor>())); })); } }
/// <summary> /// Adds Fluent Validation services to the specified /// <see cref="T:Microsoft.Extensions.DependencyInjection.IMvcBuilder" />. /// </summary> /// <returns> /// An <see cref="T:Microsoft.Extensions.DependencyInjection.IMvcBuilder" /> that can be used to further configure the /// MVC services. /// </returns> public static IMvcBuilder AddFluentValidation(this IMvcBuilder mvcBuilder, Action <FluentValidationMvcConfiguration> configurationExpression = null) { // add all IValidator to MVC's service provider var expr = configurationExpression ?? delegate { }; var config = new FluentValidationMvcConfiguration(); expr(config); if (config.AssembliesToRegister.Count > 0) { RegisterTypes(config.AssembliesToRegister, mvcBuilder.Services); } RegisterServices(mvcBuilder.Services, config); // clear all model validation providers since fluent validation will be handling everything if (config.ClearValidatorProviders) { mvcBuilder.AddMvcOptions( options => { options.ModelValidatorProviders.Clear(); }); } return(mvcBuilder); }
/// <summary> /// Adds Fluent Validation services to the specified /// <see cref="T:Microsoft.Extensions.DependencyInjection.IMvcBuilder" />. /// </summary> /// <returns> /// An <see cref="T:Microsoft.Extensions.DependencyInjection.IMvcCoreBuilder" /> that can be used to further configure the /// MVC services. /// </returns> public static IMvcCoreBuilder AddFluentValidation(this IMvcCoreBuilder mvcBuilder, Action <FluentValidationMvcConfiguration> configurationExpression = null) { var expr = configurationExpression ?? delegate { }; var config = new FluentValidationMvcConfiguration(); expr(config); if (config.AssembliesToRegister.Count > 0) { RegisterTypes(config.AssembliesToRegister, mvcBuilder.Services); } RegisterServices(mvcBuilder.Services, config); // clear all model validation providers since fluent validation will be handling everything #pragma warning disable CS0612 // Type or member is obsolete if (config.ClearValidatorProviders) { #pragma warning restore CS0612 // Type or member is obsolete mvcBuilder.AddMvcOptions( options => { options.ModelValidatorProviders.Clear(); }); } mvcBuilder.AddMvcOptions(options => { options.ModelMetadataDetailsProviders.Add(new FluentValidationBindingMetadataProvider()); options.ModelValidatorProviders.Insert(0, new FluentValidationModelValidatorProvider(config.ImplicitlyValidateChildProperties)); }); return(mvcBuilder); }
private static void RegisterServices(IServiceCollection services, FluentValidationMvcConfiguration config) { if (config.ValidatorFactory != null) { // Allow user to register their own IValidatorFactory instance, before falling back to try resolving by Type. var factory = config.ValidatorFactory; services.Add(ServiceDescriptor.Transient(s => factory)); } else { services.Add(ServiceDescriptor.Transient(typeof(IValidatorFactory), config.ValidatorFactoryType ?? typeof(ServiceProviderValidatorFactory))); } services.Add(ServiceDescriptor.Singleton <IObjectModelValidator, FluentValidationObjectModelValidator>(s => { var options = s.GetRequiredService <IOptions <MvcOptions> >().Value; var metadataProvider = s.GetRequiredService <IModelMetadataProvider>(); var modelValidator = new FluentValidationObjectModelValidator(metadataProvider, options.ModelValidatorProviders); modelValidator.RunDefaultMvcValidation = config.RunDefaultMvcValidationAfterFluentValidationExecutes; // modelValidator.ImplicitlyValidateChildProperties = config.ImplicitlyValidateChildProperties; return(modelValidator); })); // Ensure the HttpContextAccessor is registered (by default it isn't, but may have been added by features such as AddIdentity) services.TryAddSingleton <IHttpContextAccessor, HttpContextAccessor>(); if (config.ClientsideEnabled) { services.TryAddEnumerable(ServiceDescriptor.Transient <IConfigureOptions <MvcViewOptions>, FluentValidationViewOptionsSetup>(s => { return(new FluentValidationViewOptionsSetup(s.GetService <IValidatorFactory>(), config.ClientsideConfig, s.GetService <IHttpContextAccessor>())); })); } }
private static void RegisterServices(IServiceCollection services, FluentValidationMvcConfiguration config) { services.Add(ServiceDescriptor.Singleton(typeof(IValidatorFactory), config.ValidatorFactoryType ?? typeof(ServiceProviderValidatorFactory))); services.Add(ServiceDescriptor.Singleton <IObjectModelValidator, FluentValidationObjectModelValidator>(s => { var options = s.GetRequiredService <IOptions <MvcOptions> >().Value; var metadataProvider = s.GetRequiredService <IModelMetadataProvider>(); return(new FluentValidationObjectModelValidator(metadataProvider, options.ModelValidatorProviders, s.GetRequiredService <IValidatorFactory>())); })); }
/// <summary> /// Adds Fluent Validation services to the specified /// <see cref="T:Microsoft.Extensions.DependencyInjection.IMvcBuilder" />. /// </summary> /// <returns> /// An <see cref="T:Microsoft.Extensions.DependencyInjection.IMvcBuilder" /> that can be used to further configure the /// MVC services. /// </returns> public static IMvcBuilder AddFluentValidation(this IMvcBuilder mvcBuilder, Action <FluentValidationMvcConfiguration> configurationExpression = null) { var config = new FluentValidationMvcConfiguration(ValidatorOptions.Global); configurationExpression?.Invoke(config); RegisterServices(mvcBuilder.Services, config); mvcBuilder.AddMvcOptions(options => { options.ModelMetadataDetailsProviders.Add(new FluentValidationBindingMetadataProvider()); options.ModelValidatorProviders.Insert(0, new FluentValidationModelValidatorProvider(config.ImplicitlyValidateChildProperties)); }); return(mvcBuilder); }
/// <summary> /// Adds Fluent Validation services to the specified /// <see cref="T:Microsoft.Extensions.DependencyInjection.IMvcBuilder" />. /// </summary> /// <returns> /// An <see cref="T:Microsoft.Extensions.DependencyInjection.IMvcCoreBuilder" /> that can be used to further configure the /// MVC services. /// </returns> public static IMvcCoreBuilder AddFluentValidation(this IMvcCoreBuilder mvcBuilder, Action <FluentValidationMvcConfiguration> configurationExpression = null) { var expr = configurationExpression ?? delegate { }; var config = new FluentValidationMvcConfiguration(); expr(config); mvcBuilder.Services.AddValidatorsFromAssemblies(config.AssembliesToRegister); RegisterServices(mvcBuilder.Services, config); // clear all model validation providers since fluent validation will be handling everything mvcBuilder.AddMvcOptions(options => { options.ModelMetadataDetailsProviders.Add(new FluentValidationBindingMetadataProvider()); options.ModelValidatorProviders.Insert(0, new FluentValidationModelValidatorProvider(config.ImplicitlyValidateChildProperties)); }); return(mvcBuilder); }
private static void RegisterServices(IServiceCollection services, FluentValidationMvcConfiguration config) { if (config.ValidatorFactory != null) { // Allow user to register their own IValidatorFactory instance, before falling back to try resolving by Type. var factory = config.ValidatorFactory; services.Add(ServiceDescriptor.Singleton(s => factory)); } else { services.Add(ServiceDescriptor.Singleton(typeof(IValidatorFactory), config.ValidatorFactoryType ?? typeof(ServiceProviderValidatorFactory))); } services.Add(ServiceDescriptor.Singleton <IObjectModelValidator, FluentValidationObjectModelValidator>(s => { var options = s.GetRequiredService <IOptions <MvcOptions> >().Value; var metadataProvider = s.GetRequiredService <IModelMetadataProvider>(); return(new FluentValidationObjectModelValidator(metadataProvider, options.ModelValidatorProviders, s.GetRequiredService <IValidatorFactory>())); })); }
/// <summary> /// Adds Fluent Validation services to the specified /// <see cref="T:Microsoft.Extensions.DependencyInjection.IServiceCollection" />. /// </summary> /// <returns> /// A reference to this instance after the operation has completed. /// </returns> public static IServiceCollection AddFluentValidation(this IServiceCollection services, Action <FluentValidationMvcConfiguration> configurationExpression = null) { var config = new FluentValidationMvcConfiguration(ValidatorOptions.Global); configurationExpression?.Invoke(config); services.AddValidatorsFromAssemblies(config.AssembliesToRegister, config.ServiceLifetime, config.TypeFilter, config.IncludeInternalValidatorTypes); services.AddSingleton(config.ValidatorOptions); if (config.ValidatorFactory != null) { // Allow user to register their own IValidatorFactory instance, before falling back to try resolving by Type. var factory = config.ValidatorFactory; services.Add(ServiceDescriptor.Scoped(s => factory)); } else { services.Add(ServiceDescriptor.Scoped(typeof(IValidatorFactory), config.ValidatorFactoryType ?? typeof(ServiceProviderValidatorFactory))); } if (config.AutomaticValidationEnabled) { services.Add(ServiceDescriptor.Singleton <IObjectModelValidator, FluentValidationObjectModelValidator>(s => { var options = s.GetRequiredService <IOptions <MvcOptions> >().Value; var metadataProvider = s.GetRequiredService <IModelMetadataProvider>(); return(new FluentValidationObjectModelValidator(metadataProvider, options.ModelValidatorProviders, !config.DisableDataAnnotationsValidation)); })); } if (config.ClientsideEnabled) { // Clientside validation requires access to the HttpContext, but MVC's clientside API does not provide it, // so we need to inject the HttpContextAccessor instead. // This is not registered by default, so add it in if the user hasn't done so. services.AddHttpContextAccessor(); services.TryAddEnumerable(ServiceDescriptor.Singleton <IConfigureOptions <MvcViewOptions>, FluentValidationViewOptionsSetup>(s => { return(new FluentValidationViewOptionsSetup(config.ClientsideConfig, s.GetService <IHttpContextAccessor>())); })); } services.Configure <MvcOptions>(options => { // Check if the providers have already been added. // We shouldn't have to do this, but there's a bug in the ASP.NET Core integration // testing components that can cause Configureservices to be called multple times // meaning we end up with duplicates. if (!options.ModelMetadataDetailsProviders.Any(x => x is FluentValidationBindingMetadataProvider)) { options.ModelMetadataDetailsProviders.Add(new FluentValidationBindingMetadataProvider()); } if (!options.ModelValidatorProviders.Any(x => x is FluentValidationModelValidatorProvider)) { options.ModelValidatorProviders.Insert(0, new FluentValidationModelValidatorProvider( config.ImplicitlyValidateChildProperties, config.ImplicitlyValidateRootCollectionElements)); } }); return(services); }