mirror of https://github.com/abpframework/abp
parent
a8c3c9e7db
commit
57256272f2
@ -0,0 +1,7 @@
|
||||
namespace Volo.Abp.Validation
|
||||
{
|
||||
public interface IMethodInvocationValidator
|
||||
{
|
||||
void Validate(MethodInvocationValidationContext context);
|
||||
}
|
||||
}
|
||||
@ -1,13 +0,0 @@
|
||||
namespace Volo.Abp.Validation
|
||||
{
|
||||
/// <summary>
|
||||
/// This interface is used to normalize inputs before method execution.
|
||||
/// </summary>
|
||||
public interface IShouldNormalize
|
||||
{
|
||||
/// <summary>
|
||||
/// This method is called lastly before method execution (after validation if exists).
|
||||
/// </summary>
|
||||
void Normalize();
|
||||
}
|
||||
}
|
||||
@ -1,19 +1,96 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using Volo.Abp.DependencyInjection;
|
||||
using Volo.Abp.Reflection;
|
||||
|
||||
namespace Volo.Abp.Validation
|
||||
{
|
||||
/// <summary>
|
||||
/// This class is used to validate a method call (invocation) for method arguments.
|
||||
/// </summary>
|
||||
public class MethodInvocationValidator : MethodInvocationValidatorBase
|
||||
public class MethodInvocationValidator : IMethodInvocationValidator, ITransientDependency
|
||||
{
|
||||
public MethodInvocationValidator(IObjectValidator objectValidator)
|
||||
: base(objectValidator)
|
||||
{
|
||||
private readonly IObjectValidator _objectValidator;
|
||||
|
||||
public MethodInvocationValidator(IObjectValidator objectValidator)
|
||||
{
|
||||
_objectValidator = objectValidator;
|
||||
}
|
||||
|
||||
public virtual void Validate(MethodInvocationValidationContext context)
|
||||
{
|
||||
ValidateInternal(context);
|
||||
Check.NotNull(context, nameof(context));
|
||||
|
||||
if (context.Parameters.IsNullOrEmpty())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (!context.Method.IsPublic)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (IsValidationDisabled(context))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (context.Parameters.Length != context.ParameterValues.Length)
|
||||
{
|
||||
throw new Exception("Method parameter count does not match with argument count!");
|
||||
}
|
||||
|
||||
if (context.Errors.Any() && HasSingleNullArgument(context))
|
||||
{
|
||||
ThrowValidationError(context);
|
||||
}
|
||||
|
||||
AddMethodParameterValidationErrors(context);
|
||||
|
||||
if (context.Errors.Any())
|
||||
{
|
||||
ThrowValidationError(context);
|
||||
}
|
||||
}
|
||||
|
||||
protected virtual bool IsValidationDisabled(MethodInvocationValidationContext context)
|
||||
{
|
||||
if (context.Method.IsDefined(typeof(EnableValidationAttribute), true))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return ReflectionHelper.GetSingleAttributeOfMemberOrDeclaringTypeOrDefault<DisableValidationAttribute>(context.Method) != null;
|
||||
}
|
||||
|
||||
protected virtual bool HasSingleNullArgument(MethodInvocationValidationContext context)
|
||||
{
|
||||
return context.Parameters.Length == 1 && context.ParameterValues[0] == null;
|
||||
}
|
||||
|
||||
protected virtual void ThrowValidationError(MethodInvocationValidationContext context)
|
||||
{
|
||||
throw new AbpValidationException(
|
||||
"Method arguments are not valid! See ValidationErrors for details.",
|
||||
context.Errors
|
||||
);
|
||||
}
|
||||
|
||||
protected virtual void AddMethodParameterValidationErrors(MethodInvocationValidationContext context)
|
||||
{
|
||||
for (var i = 0; i < context.Parameters.Length; i++)
|
||||
{
|
||||
AddMethodParameterValidationErrors(context, context.Parameters[i], context.ParameterValues[i]);
|
||||
}
|
||||
}
|
||||
|
||||
protected virtual void AddMethodParameterValidationErrors(IAbpValidationResult context, ParameterInfo parameterInfo, object parameterValue)
|
||||
{
|
||||
var allowNulls = parameterInfo.IsOptional ||
|
||||
parameterInfo.IsOut ||
|
||||
TypeHelper.IsPrimitiveExtendedIncludingNullable(parameterInfo.ParameterType, includeEnums: true);
|
||||
|
||||
_objectValidator.AddErrors(context, parameterValue, parameterInfo.Name, allowNulls);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1,105 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using Volo.Abp.DependencyInjection;
|
||||
using Volo.Abp.Reflection;
|
||||
|
||||
namespace Volo.Abp.Validation
|
||||
{
|
||||
public abstract class MethodInvocationValidatorBase : ITransientDependency
|
||||
{
|
||||
private readonly IObjectValidator _objectValidator;
|
||||
|
||||
protected MethodInvocationValidatorBase(IObjectValidator objectValidator)
|
||||
{
|
||||
_objectValidator = objectValidator;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Validates the method invocation.
|
||||
/// </summary>
|
||||
protected virtual void ValidateInternal(MethodInvocationValidationContext context)
|
||||
{
|
||||
Check.NotNull(context, nameof(context));
|
||||
|
||||
if (context.Parameters.IsNullOrEmpty())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (!context.Method.IsPublic)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (IsValidationDisabled(context))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (context.Parameters.Length != context.ParameterValues.Length)
|
||||
{
|
||||
throw new Exception("Method parameter count does not match with argument count!");
|
||||
}
|
||||
|
||||
if (context.Errors.Any() && HasSingleNullArgument(context))
|
||||
{
|
||||
ThrowValidationError(context);
|
||||
}
|
||||
|
||||
AddMethodParameterValidationErrors(context);
|
||||
|
||||
if (context.Errors.Any())
|
||||
{
|
||||
ThrowValidationError(context);
|
||||
}
|
||||
|
||||
foreach (var objectToBeNormalized in context.ObjectsToBeNormalized)
|
||||
{
|
||||
objectToBeNormalized.Normalize();
|
||||
}
|
||||
}
|
||||
|
||||
protected virtual bool IsValidationDisabled(MethodInvocationValidationContext context)
|
||||
{
|
||||
if (context.Method.IsDefined(typeof(EnableValidationAttribute), true))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return ReflectionHelper.GetSingleAttributeOfMemberOrDeclaringTypeOrDefault<DisableValidationAttribute>(context.Method) != null;
|
||||
}
|
||||
|
||||
protected virtual bool HasSingleNullArgument(MethodInvocationValidationContext context)
|
||||
{
|
||||
return context.Parameters.Length == 1 && context.ParameterValues[0] == null;
|
||||
}
|
||||
|
||||
protected virtual void ThrowValidationError(MethodInvocationValidationContext context)
|
||||
{
|
||||
throw new AbpValidationException(
|
||||
"Method arguments are not valid! See ValidationErrors for details.",
|
||||
context.Errors
|
||||
);
|
||||
}
|
||||
|
||||
protected virtual void AddMethodParameterValidationErrors(MethodInvocationValidationContext context)
|
||||
{
|
||||
for (var i = 0; i < context.Parameters.Length; i++)
|
||||
{
|
||||
AddMethodParameterValidationErrors(context, context.Parameters[i], context.ParameterValues[i]);
|
||||
}
|
||||
}
|
||||
|
||||
protected virtual void AddMethodParameterValidationErrors(IAbpValidationResult context, ParameterInfo parameterInfo, object parameterValue)
|
||||
{
|
||||
var allowNulls = parameterInfo.IsOptional ||
|
||||
parameterInfo.IsOut ||
|
||||
TypeHelper.IsPrimitiveExtendedIncludingNullable(parameterInfo.ParameterType, includeEnums: true);
|
||||
|
||||
_objectValidator.AddValidatationErrors(context, parameterValue, parameterInfo.Name, allowNulls);
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
Reference in new issue