Пример #1
0
 public ActionLog(IValidatable validatable)
 {
     TypeName          = validatable.GetType().Name;
     Parameters        = AssemblyHelper.GetPropertiesWithValues(validatable);
     ActionDescription = AssemblyHelper.GetDescription(validatable.GetType());
     ActionId          = Guid.NewGuid();
 }
        /// <summary>
        /// Validates the specified property.
        /// </summary>
        /// <param name="property">The property that will its value validated.</param>
        /// <param name="sender">The sender who owns the property.</param>
        /// <returns>
        /// Returns a validation message if validation failed. Otherwise null is returned to indicate a passing validation.
        /// </returns>
        /// <exception cref="System.MissingMethodException"></exception>
        public override IValidationMessage Validate(System.Reflection.PropertyInfo property, IValidatable sender)
        {
            if (!this.CanValidate(sender))
            {
                return null;
            }

            // Set up localization if available.
            this.PrepareLocalization();

            // Create an instance of our validation message and return it if there is not a delegate specified.
            IValidationMessage validationMessage = Activator.CreateInstance(this.ValidationMessageType, this.FailureMessage) as IValidationMessage;
            if (string.IsNullOrEmpty(this.DelegateName))
            {
                return validationMessage;
            }

            // Find our delegate method.
            IEnumerable<MethodInfo> validationMethods = sender
                .GetType()
                .GetMethods(BindingFlags.Public | BindingFlags.Instance | BindingFlags.NonPublic)
                .Where(m => m.GetCustomAttributes(typeof(ValidationCustomHandlerDelegate), true).Any());

            MethodInfo validationDelegate = validationMethods.FirstOrDefault(m => m
                    .GetCustomAttributes(typeof(ValidationCustomHandlerDelegate), true)
                    .FirstOrDefault(del => (del as ValidationCustomHandlerDelegate).DelegateName == this.DelegateName) != null);

            if (validationDelegate == null)
            {
                throw new MissingMemberException(
                    string.Format("Missing {0} validation delegate for {1} instance.", this.DelegateName, sender.GetType()));
            }

            // Attempt to invoke our delegate method.
            object result = null;
            try
            {
                 result = validationDelegate.Invoke(sender, new object[] { validationMessage, property });

            }
            catch (Exception)
            {
                throw;
            }

            // Return the results of the delegate method.
            if (result != null && result is IValidationMessage)
            {
                return result as IValidationMessage;
            }
            else if (result == null)
            {
                return null;
            }

            return validationMessage;
        }
Пример #3
0
        public static ValidationResult Validate <T>(this IValidatable validatable, IServiceProvider serviceProvider = null, bool throwOnNotValidable = false, bool throwOnValidationError = false)
            where T : class, IValidator
        {
            if (validatable is null)
            {
                throw new ArgumentNullException(nameof(validatable));
            }

            var validator = serviceProvider is null
                ? Activator.CreateInstance <T>()
                : ActivatorUtilities.CreateInstance <T>(serviceProvider);

            if (validator.CanValidateInstancesOfType(validatable.GetType()))
            {
                var context = new ValidationContext <IValidatable>(validatable);

                var validationResult = validator.Validate(context);

                if (!validationResult.IsValid && throwOnValidationError)
                {
                    throw validationResult.ToException();
                }

                return(validationResult);
            }
            else if (throwOnNotValidable)
            {
                throw new NotSupportedException($"Validator or type {typeof(T)} does not support objects of type {validatable.GetType()}");
            }

            return(new ValidationResult());
        }
Пример #4
0
        public static ValidationResult Validate(this IValidatable validatable, IValidatorFactory validatorFactory = null, IServiceProvider serviceProvider = null, bool throwOnNoValidatorFound = false, bool throwOnValidationError = false)
        {
            if (validatable is null)
            {
                throw new ArgumentNullException(nameof(validatable));
            }

            var validators = (validatorFactory ?? ValidatorFactory.DefaultFactory).GetValidators(validatable.GetType(), serviceProvider);

            if (validators.Any())
            {
                var context = new ValidationContext <IValidatable>(validatable);

                var validationResult = validators
                                       .Select(validator => validator.Validate(context))
                                       .MergeValidationResults();

                if (!validationResult.IsValid && throwOnValidationError)
                {
                    throw validationResult.ToException();
                }

                return(validationResult);
            }

            if (throwOnNoValidatorFound)
            {
                throw new NotSupportedException($"Validation of type {validatable.GetType()} is not supported");
            }

            return(new ValidationResult());
        }
Пример #5
0
        public static bool Validate(IValidatable obj)
        {
            if (obj == null)
            {
                return(false);
            }

            bool result = true;

            try
            {
                return(!obj.GetType()
                       .GetProperties()
                       .Where(x => IsRequired(x))
                       .Any(x =>
                {
                    return x.GetValue(obj) == null;
                }));
            }
            catch (Exception e)
            {
                result = false;
            }

            return(result);
        }
Пример #6
0
        /// <summary>
        /// Validates the specified property of the specified validation source.
        /// </summary>
        /// <param name="validationSource">The validation source.</param>
        /// <param name="propertyName">Name of the property.</param>
        /// <returns>The collection of validation mesasges.</returns>
        public static ValidationMessageCollection Validate(this IValidatable validationSource, string propertyName)
        {
            validationSource.CannotBeNull();
            propertyName.CannotBeNullOrEmpty();

            ValidationMessageCollection messages = new ValidationMessageCollection();
            List <string> validationContexts;
            object        propertyValue;

            // get property value
            var properties = ReflectionExtensions.GetProperties(validationSource.GetType());

            if (properties.TryGetValue(propertyName, out PropertyData propertyData))
            {
                if (propertyData.PropertyInfo.CanRead &&
                    propertyData.PropertyInfo.CanWrite)
                {
                    propertyValue = propertyData.PropertyInfo.GetValue(validationSource);

                    // get validation context
                    validationContexts = new List <string>();
                    validationContexts.Add(ValidationContext.Default);                                                     // always add the default validation context
                    validationContexts.AddRange(validationSource.GetActiveValidationContexts() ?? Array.Empty <string>()); // add currently active validation context

                    foreach (var validationContext in validationContexts.Distinct())
                    {
                        messages.AddRange(validationSource.Validate(propertyName, propertyValue, validationContext));
                    }
                }
            }

            return(messages);
        }
Пример #7
0
        /// <summary>
        /// Validates the specified property.
        /// </summary>
        /// <param name="property">The property that will its value validated.</param>
        /// <param name="sender">The sender who owns the property.</param>
        /// <returns>
        /// Returns a validation message if validation failed. Otherwise null is returned to indicate a passing validation.
        /// </returns>
        /// <exception cref="System.MissingMethodException"></exception>
        public override IValidationMessage Validate(System.Reflection.PropertyInfo property, IValidatable sender)
        {
            if (!this.CanValidate(sender))
            {
                return(null);
            }

            // Set up localization if available.
            this.PrepareLocalization();

            // Create an instance of our validation message and return it if there is not a delegate specified.
            IValidationMessage validationMessage = Activator.CreateInstance(this.ValidationMessageType, this.FailureMessage) as IValidationMessage;

            if (string.IsNullOrEmpty(this.DelegateName))
            {
                return(validationMessage);
            }

            // Find our delegate method.
            IEnumerable <MethodInfo> validationMethods = sender
                                                         .GetType()
                                                         .GetMethods(BindingFlags.Public | BindingFlags.Instance | BindingFlags.NonPublic)
                                                         .Where(m => m.GetCustomAttributes(typeof(ValidationCustomHandlerDelegate), true).Any());

            MethodInfo validationDelegate = validationMethods.FirstOrDefault(m => m
                                                                             .GetCustomAttributes(typeof(ValidationCustomHandlerDelegate), true)
                                                                             .FirstOrDefault(del => (del as ValidationCustomHandlerDelegate).DelegateName == this.DelegateName) != null);

            if (validationDelegate == null)
            {
                throw new MissingMemberException(
                          string.Format("Missing {0} validation delegate for {1} instance.", this.DelegateName, sender.GetType()));
            }

            // Attempt to invoke our delegate method.
            object result = null;

            try
            {
                result = validationDelegate.Invoke(sender, new object[] { validationMessage, property });
            }
            catch (Exception)
            {
                throw;
            }

            // Return the results of the delegate method.
            if (result != null && result is IValidationMessage)
            {
                return(result as IValidationMessage);
            }
            else if (result == null)
            {
                return(null);
            }

            return(validationMessage);
        }
Пример #8
0
    public static async Task <ValidationResult> ValidateAsync(this IValidatable validatable, IValidatorProvider validatorFactory, bool throwOnNoValidatorFound = false, bool throwOnValidationError = false)
    {
        if (validatable is null)
        {
            throw new ArgumentNullException(nameof(validatable));
        }

        if (validatorFactory is null)
        {
            throw new ArgumentNullException(nameof(validatorFactory));
        }

        var validators = validatorFactory.GetValidators(validatable.GetType());

        if (validators.Any())
        {
            var context = new ValidationContext <IValidatable>(validatable);

            var validationTasks = validators
                                  .Select(validator => validator.ValidateAsync(context));

            var validationResults = await Task
                                    .WhenAll(validationTasks)
                                    .ConfigureAwait(false);

            var validationResult = validationResults.Merge();

            if (!validationResult.IsValid && throwOnValidationError)
            {
                throw validationResult.ToException();
            }

            return(validationResult);
        }

        if (throwOnNoValidatorFound)
        {
            throw new NotSupportedException($"Validation of type {validatable.GetType()} is not supported");
        }

        return(new ValidationResult());
    }
Пример #9
0
        public static FluentValidation.Results.ValidationResult Validate(this IValidatable obj, object additonalContext)
        {
            var validationResult = ValidationEngine.Validate(obj.GetType(), obj, additonalContext);

            if (validationResult == null || validationResult.Errors == null)
            {
                return(new FluentValidation.Results.ValidationResult());
            }

            return(validationResult);
        }
Пример #10
0
        public static string GetPropertiesWithValues(IValidatable action)
        {
            Type type = action.GetType();

            PropertyInfo[] props = type.GetProperties();
            string         str   = "";

            foreach (var prop in props)
            {
                str += (prop.Name + ":" + prop.GetValue(action)) + ",";
            }

            return(str);
        }
Пример #11
0
        /// <summary>
        /// Makes it somewhat easier to throw validation failures that have useful metadata on them (type).
        /// </summary>
        public static void ThrowValidationFailure(this IValidatable instance, string reason)
        {
            if (instance == null)
            {
                throw new ArgumentNullException("instance");
            }

            if (reason == null)
            {
                throw new ArgumentNullException("reason");
            }

            throw new ValidationException(string.Format("{0} - {1}", instance.GetType().FullName, reason));
        }
Пример #12
0
        /// <summary>
        /// Validates the the specified validation source.
        /// </summary>
        /// <param name="validationSource">The validation source.</param>
        /// <returns>
        /// The collection of validation mesasges.
        /// </returns>
        public static ValidationMessageCollection Validate(this IValidatable validationSource)
        {
            validationSource.CannotBeNull();

            ValidationMessageCollection messages = new ValidationMessageCollection();
            var propertyNames = ReflectionExtensions.GetProperties(validationSource.GetType()).Keys;

            foreach (var propertyName in propertyNames)
            {
                messages.AddRange(validationSource.Validate(propertyName));
            }

            return(messages);
        }
    public static bool ValidateAll(this IValidatable item)
    {
        if (!item.ValidateObject())
        {
            return(false);
        }
        const BindingFlags flags = BindingFlags.GetProperty | BindingFlags.Instance | BindingFlags.Public;
        var type   = item.GetType();
        var props  = type.GetProperties(flags).Select(x => x.GetValue(item));
        var fields = type.GetFields(flags).Select(x => x.GetValue(item));

        return(props
               .Concat(fields)
               .OfType <IValidatable>()
               .Select(x => x.ValidateAll())
               .All(x => x));
    }
Пример #14
0
        /// <summary>
        /// Returns a message that contains all the current errors.
        /// </summary>
        /// <param name="validatable">The model base.</param>
        /// <param name="userFriendlyObjectName">Name of the user friendly object.</param>
        /// <returns>
        /// Error string or empty in case of no errors.
        /// </returns>
        /// <exception cref="ArgumentNullException">The <paramref name="validatable"/> is <c>null</c>.</exception>
        public static string GetErrorMessage(this IValidatable validatable, string userFriendlyObjectName = null)
        {
            Argument.IsNotNull("model", validatable);

            var validationContext = validatable.ValidationContext;

            if (!validationContext.HasErrors)
            {
                return(string.Empty);
            }

            if (string.IsNullOrEmpty(userFriendlyObjectName))
            {
                // Use the real entity name (stupid developer that passes a useless value)
                userFriendlyObjectName = validatable.GetType().Name;
            }

            var messageBuilder = new StringBuilder();

            messageBuilder.AppendLine($"Found the following errors in '{userFriendlyObjectName}'");
            messageBuilder.Append(validationContext.GetValidationsAsStringList(ValidationResultType.Error));

            return(messageBuilder.ToString());
        }
Пример #15
0
        /// <summary>
        /// Validates the specified property of the specified validation source for the specified property value in specified validation context by using validation attributes.
        /// </summary>
        /// <param name="validationSource">The validation source.</param>
        /// <param name="propertyName">The property name.</param>
        /// <param name="propertyValue">The property value.</param>
        /// <param name="validationContext">The validation context.</param>
        /// <returns>
        /// The collection of validation mesasges.
        /// </returns>
        public static ValidationMessageCollection ValidateAttributes(this IValidatable validationSource, string propertyName, object propertyValue, string validationContext)
        {
            validationSource.CannotBeNull();
            propertyName.CannotBeNullOrEmpty();

            ValidationMessageCollection messages = new ValidationMessageCollection();
            var  validationAttributes            = ReflectionExtensions.GetProperties(validationSource.GetType())[propertyName].ValidationAttributes;
            bool isValid;

            // perform attribute based validation
            foreach (var validationAttribute in validationAttributes)
            {
                // only matching validation context gets validated
                if (validationAttribute.ValidationContext == validationContext)
                {
                    // custom validators might cause exceptions that are hard to find
                    try
                    {
                        isValid = validationAttribute.IsValid(propertyValue);
                    }
                    catch (Exception ex)
                    {
                        throw new ValidationErrorException("Unhandled validation exception occurred.", validationAttribute.GetType(), validationSource.GetType(), propertyName, ex);
                    }

                    if (!isValid)
                    {
                        var messageKey         = validationAttribute.MessageKey ?? validationAttribute.GetDefaultMessageKey() ?? "UndefinedMessageKey";
                        var message            = validationAttribute.Message ?? validationAttribute.GetDefaultMessage() ?? "Undefined message.";
                        var messageParameters  = validationAttribute.MessageParameters;
                        var validationLevel    = validationAttribute.ValidationLevel;
                        var validationPriority = validationAttribute.ValidationPriority;

                        // value is invalid -> add it to the list
                        messages.Add(new ValidationMessage(messageKey, message, messageParameters, validationSource, propertyName, validationLevel, validationContext, validationPriority));
                    }
                }
            }

            return(messages);
        }