Browse Source

Make IObjectValidator async.

Resolve #9544
pull/9549/head
maliming 5 years ago
parent
commit
d2e52f64f2
  1. 5
      framework/src/Volo.Abp.FluentValidation/Volo/Abp/FluentValidation/FluentObjectValidationContributor.cs
  2. 4
      framework/src/Volo.Abp.Validation/Volo/Abp/Validation/DataAnnotationObjectValidationContributor.cs
  3. 6
      framework/src/Volo.Abp.Validation/Volo/Abp/Validation/IMethodInvocationValidator.cs
  4. 8
      framework/src/Volo.Abp.Validation/Volo/Abp/Validation/IObjectValidationContributor.cs
  5. 7
      framework/src/Volo.Abp.Validation/Volo/Abp/Validation/IObjectValidator.cs
  6. 17
      framework/src/Volo.Abp.Validation/Volo/Abp/Validation/MethodInvocationValidator.cs
  7. 9
      framework/src/Volo.Abp.Validation/Volo/Abp/Validation/ObjectValidator.cs
  8. 6
      framework/src/Volo.Abp.Validation/Volo/Abp/Validation/ValidationInterceptor.cs
  9. 27
      framework/test/Volo.Abp.FluentValidation.Tests/Volo/Abp/FluentValidation/ApplicationService_FluentValidation_Tests.cs

5
framework/src/Volo.Abp.FluentValidation/Volo/Abp/FluentValidation/FluentObjectValidationContributor.cs

@ -2,6 +2,7 @@ using FluentValidation;
using System; using System;
using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations;
using System.Linq; using System.Linq;
using System.Threading.Tasks;
using Volo.Abp.DependencyInjection; using Volo.Abp.DependencyInjection;
using Volo.Abp.Validation; using Volo.Abp.Validation;
@ -17,7 +18,7 @@ namespace Volo.Abp.FluentValidation
_serviceProvider = serviceProvider; _serviceProvider = serviceProvider;
} }
public void AddErrors(ObjectValidationContext context) public virtual async Task AddErrorsAsync(ObjectValidationContext context)
{ {
var serviceType = typeof(IValidator<>).MakeGenericType(context.ValidatingObject.GetType()); var serviceType = typeof(IValidator<>).MakeGenericType(context.ValidatingObject.GetType());
var validator = _serviceProvider.GetService(serviceType) as IValidator; var validator = _serviceProvider.GetService(serviceType) as IValidator;
@ -26,7 +27,7 @@ namespace Volo.Abp.FluentValidation
return; return;
} }
var result = validator.Validate((IValidationContext) Activator.CreateInstance( var result = await validator.ValidateAsync((IValidationContext) Activator.CreateInstance(
typeof(ValidationContext<>).MakeGenericType(context.ValidatingObject.GetType()), typeof(ValidationContext<>).MakeGenericType(context.ValidatingObject.GetType()),
context.ValidatingObject)); context.ValidatingObject));

4
framework/src/Volo.Abp.Validation/Volo/Abp/Validation/DataAnnotationObjectValidationContributor.cs

@ -4,6 +4,7 @@ using System.Collections.Generic;
using System.ComponentModel; using System.ComponentModel;
using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations;
using System.Linq; using System.Linq;
using System.Threading.Tasks;
using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Options; using Microsoft.Extensions.Options;
using Volo.Abp.DependencyInjection; using Volo.Abp.DependencyInjection;
@ -26,9 +27,10 @@ namespace Volo.Abp.Validation
Options = options.Value; Options = options.Value;
} }
public void AddErrors(ObjectValidationContext context) public Task AddErrorsAsync(ObjectValidationContext context)
{ {
ValidateObjectRecursively(context.Errors, context.ValidatingObject, currentDepth: 1); ValidateObjectRecursively(context.Errors, context.ValidatingObject, currentDepth: 1);
return Task.CompletedTask;
} }
protected virtual void ValidateObjectRecursively(List<ValidationResult> errors, object validatingObject, int currentDepth) protected virtual void ValidateObjectRecursively(List<ValidationResult> errors, object validatingObject, int currentDepth)

6
framework/src/Volo.Abp.Validation/Volo/Abp/Validation/IMethodInvocationValidator.cs

@ -1,7 +1,9 @@
namespace Volo.Abp.Validation using System.Threading.Tasks;
namespace Volo.Abp.Validation
{ {
public interface IMethodInvocationValidator public interface IMethodInvocationValidator
{ {
void Validate(MethodInvocationValidationContext context); Task ValidateAsync(MethodInvocationValidationContext context);
} }
} }

8
framework/src/Volo.Abp.Validation/Volo/Abp/Validation/IObjectValidationContributor.cs

@ -1,7 +1,9 @@
namespace Volo.Abp.Validation using System.Threading.Tasks;
namespace Volo.Abp.Validation
{ {
public interface IObjectValidationContributor public interface IObjectValidationContributor
{ {
void AddErrors(ObjectValidationContext context); Task AddErrorsAsync(ObjectValidationContext context);
} }
} }

7
framework/src/Volo.Abp.Validation/Volo/Abp/Validation/IObjectValidator.cs

@ -1,20 +1,21 @@
using System.Collections.Generic; using System.Collections.Generic;
using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations;
using System.Threading.Tasks;
namespace Volo.Abp.Validation namespace Volo.Abp.Validation
{ {
public interface IObjectValidator public interface IObjectValidator
{ {
void Validate( Task ValidateAsync(
object validatingObject, object validatingObject,
string name = null, string name = null,
bool allowNull = false bool allowNull = false
); );
List<ValidationResult> GetErrors( Task<List<ValidationResult>> GetErrorsAsync(
object validatingObject, object validatingObject,
string name = null, string name = null,
bool allowNull = false bool allowNull = false
); );
} }
} }

17
framework/src/Volo.Abp.Validation/Volo/Abp/Validation/MethodInvocationValidator.cs

@ -2,6 +2,7 @@ using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Reflection; using System.Reflection;
using System.Threading.Tasks;
using Volo.Abp.DependencyInjection; using Volo.Abp.DependencyInjection;
using Volo.Abp.Reflection; using Volo.Abp.Reflection;
@ -16,7 +17,7 @@ namespace Volo.Abp.Validation
_objectValidator = objectValidator; _objectValidator = objectValidator;
} }
public virtual void Validate(MethodInvocationValidationContext context) public virtual async Task ValidateAsync(MethodInvocationValidationContext context)
{ {
Check.NotNull(context, nameof(context)); Check.NotNull(context, nameof(context));
@ -46,7 +47,7 @@ namespace Volo.Abp.Validation
ThrowValidationError(context); ThrowValidationError(context);
} }
AddMethodParameterValidationErrors(context); await AddMethodParameterValidationErrorsAsync(context);
if (context.Errors.Any()) if (context.Errors.Any())
{ {
@ -60,7 +61,7 @@ namespace Volo.Abp.Validation
{ {
return false; return false;
} }
if (ReflectionHelper.GetSingleAttributeOfMemberOrDeclaringTypeOrDefault<DisableValidationAttribute>(context.Method) != null) if (ReflectionHelper.GetSingleAttributeOfMemberOrDeclaringTypeOrDefault<DisableValidationAttribute>(context.Method) != null)
{ {
return true; return true;
@ -82,22 +83,22 @@ namespace Volo.Abp.Validation
); );
} }
protected virtual void AddMethodParameterValidationErrors(MethodInvocationValidationContext context) protected virtual async Task AddMethodParameterValidationErrorsAsync(MethodInvocationValidationContext context)
{ {
for (var i = 0; i < context.Parameters.Length; i++) for (var i = 0; i < context.Parameters.Length; i++)
{ {
AddMethodParameterValidationErrors(context, context.Parameters[i], context.ParameterValues[i]); await AddMethodParameterValidationErrorsAsync(context, context.Parameters[i], context.ParameterValues[i]);
} }
} }
protected virtual void AddMethodParameterValidationErrors(IAbpValidationResult context, ParameterInfo parameterInfo, object parameterValue) protected virtual async Task AddMethodParameterValidationErrorsAsync(IAbpValidationResult context, ParameterInfo parameterInfo, object parameterValue)
{ {
var allowNulls = parameterInfo.IsOptional || var allowNulls = parameterInfo.IsOptional ||
parameterInfo.IsOut || parameterInfo.IsOut ||
TypeHelper.IsPrimitiveExtended(parameterInfo.ParameterType, includeEnums: true); TypeHelper.IsPrimitiveExtended(parameterInfo.ParameterType, includeEnums: true);
context.Errors.AddRange( context.Errors.AddRange(
_objectValidator.GetErrors( await _objectValidator.GetErrorsAsync(
parameterValue, parameterValue,
parameterInfo.Name, parameterInfo.Name,
allowNulls allowNulls
@ -105,4 +106,4 @@ namespace Volo.Abp.Validation
); );
} }
} }
} }

9
framework/src/Volo.Abp.Validation/Volo/Abp/Validation/ObjectValidator.cs

@ -2,6 +2,7 @@ using Microsoft.Extensions.Options;
using System.Collections.Generic; using System.Collections.Generic;
using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations;
using System.Linq; using System.Linq;
using System.Threading.Tasks;
using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection;
using Volo.Abp.DependencyInjection; using Volo.Abp.DependencyInjection;
@ -18,9 +19,9 @@ namespace Volo.Abp.Validation
Options = options.Value; Options = options.Value;
} }
public virtual void Validate(object validatingObject, string name = null, bool allowNull = false) public virtual async Task ValidateAsync(object validatingObject, string name = null, bool allowNull = false)
{ {
var errors = GetErrors(validatingObject, name, allowNull); var errors = await GetErrorsAsync(validatingObject, name, allowNull);
if (errors.Any()) if (errors.Any())
{ {
@ -31,7 +32,7 @@ namespace Volo.Abp.Validation
} }
} }
public virtual List<ValidationResult> GetErrors(object validatingObject, string name = null, bool allowNull = false) public virtual async Task<List<ValidationResult>> GetErrorsAsync(object validatingObject, string name = null, bool allowNull = false)
{ {
if (validatingObject == null) if (validatingObject == null)
{ {
@ -58,7 +59,7 @@ namespace Volo.Abp.Validation
{ {
var contributor = (IObjectValidationContributor) var contributor = (IObjectValidationContributor)
scope.ServiceProvider.GetRequiredService(contributorType); scope.ServiceProvider.GetRequiredService(contributorType);
contributor.AddErrors(context); await contributor.AddErrorsAsync(context);
} }
} }

6
framework/src/Volo.Abp.Validation/Volo/Abp/Validation/ValidationInterceptor.cs

@ -15,13 +15,13 @@ namespace Volo.Abp.Validation
public override async Task InterceptAsync(IAbpMethodInvocation invocation) public override async Task InterceptAsync(IAbpMethodInvocation invocation)
{ {
Validate(invocation); await ValidateAsync(invocation);
await invocation.ProceedAsync(); await invocation.ProceedAsync();
} }
protected virtual void Validate(IAbpMethodInvocation invocation) protected virtual async Task ValidateAsync(IAbpMethodInvocation invocation)
{ {
_methodInvocationValidator.Validate( await _methodInvocationValidator.ValidateAsync(
new MethodInvocationValidationContext( new MethodInvocationValidationContext(
invocation.TargetObject, invocation.TargetObject,
invocation.Method, invocation.Method,

27
framework/test/Volo.Abp.FluentValidation.Tests/Volo/Abp/FluentValidation/ApplicationService_FluentValidation_Tests.cs

@ -39,7 +39,8 @@ namespace Volo.Abp.FluentValidation
}, },
MyMethodInput3 = new MyMethodInput3 MyMethodInput3 = new MyMethodInput3
{ {
MyStringValue3 = "ccc" MyStringValue3 = "ccc",
MyBoolValue3 = true
} }
}); });
@ -62,12 +63,13 @@ namespace Volo.Abp.FluentValidation
}, },
MyMethodInput3 = new MyMethodInput3 MyMethodInput3 = new MyMethodInput3
{ {
MyStringValue3 = "c" MyStringValue3 = "c",
MyBoolValue3 = false
} }
} }
) )
); );
exception.ValidationErrors.ShouldContain(x => x.MemberNames.Contains("MyStringValue")); exception.ValidationErrors.ShouldContain(x => x.MemberNames.Contains("MyStringValue"));
exception.ValidationErrors.ShouldContain(x => x.MemberNames.Contains("MyMethodInput2.MyStringValue2")); exception.ValidationErrors.ShouldContain(x => x.MemberNames.Contains("MyMethodInput2.MyStringValue2"));
exception.ValidationErrors.ShouldContain(x => x.MemberNames.Contains("MyMethodInput3.MyStringValue3")); exception.ValidationErrors.ShouldContain(x => x.MemberNames.Contains("MyMethodInput3.MyStringValue3"));
@ -100,7 +102,7 @@ namespace Volo.Abp.FluentValidation
output.ShouldBe("444"); output.ShouldBe("444");
} }
[DependsOn(typeof(AbpAutofacModule))] [DependsOn(typeof(AbpAutofacModule))]
[DependsOn(typeof(AbpFluentValidationModule))] [DependsOn(typeof(AbpFluentValidationModule))]
public class TestModule : AbpModule public class TestModule : AbpModule
@ -162,6 +164,8 @@ namespace Volo.Abp.FluentValidation
{ {
public string MyStringValue3 { get; set; } public string MyStringValue3 { get; set; }
public bool MyBoolValue3 { get; set; }
} }
public class MyMethodInput4 public class MyMethodInput4
@ -175,7 +179,8 @@ namespace Volo.Abp.FluentValidation
{ {
RuleFor(x => x.MyStringValue).Equal("aaa"); RuleFor(x => x.MyStringValue).Equal("aaa");
RuleFor(x => x.MyMethodInput2.MyStringValue2).Equal("bbb"); RuleFor(x => x.MyMethodInput2.MyStringValue2).Equal("bbb");
RuleFor(customer => customer.MyMethodInput3).SetValidator(new MyMethodInput3Validator()); RuleFor(x => x.MyMethodInput3).SetValidator(new MyMethodInput3Validator());
RuleFor(x => x.MyMethodInput3).SetValidator(new MyMethodInput3AsyncValidator());
} }
} }
@ -194,5 +199,15 @@ namespace Volo.Abp.FluentValidation
RuleFor(x => x.MyStringValue3).Equal("ccc"); RuleFor(x => x.MyStringValue3).Equal("ccc");
} }
} }
public class MyMethodInput3AsyncValidator : MethodInputBaseValidator
{
public MyMethodInput3AsyncValidator()
{
RuleFor(x => x.MyStringValue3).Equal("ccc");
RuleFor(x => x.MyBoolValue3).MustAsync((myBookValue3, cancellation) => Task.FromResult(myBookValue3));
}
}
} }
} }

Loading…
Cancel
Save