/// <summary>
		/// Validates the parameter.
		/// </summary>
		/// <param name="invocation">The invocation.</param>
		/// <param name="parameterPosition">The parameter position.</param>
		/// <param name="runWhen">The run when.</param>
		/// <param name="errors">The errors.</param>
		protected virtual void ValidateParameter(IInvocation invocation, int parameterPosition, RunWhen runWhen, ErrorSummary errors)
		{
			MethodInfo method = invocation.Method;


			ParameterInfoMeta parameterInfoMeta;
			IValidator[] validators = methodValidatorMetaStore.GetValidatorsFor(method, parameterPosition, null, runWhen, out parameterInfoMeta);

			foreach (IValidator validator in validators)
			{
				IPropertyAccessAware propertyAccessAware = (IPropertyAccessAware)validator;
				object value = invocation.Arguments[parameterPosition];

				if (parameterInfoMeta == ParameterInfoMeta.ParamsArray)
				{
					ValidateParamsArray(validator, propertyAccessAware, value, errors);
					continue;
				}

				propertyAccessAware.PropertyAccessor = delegate { return invocation.Arguments[parameterPosition]; };
					
				if (validator.IsValid(value)) 
					continue;

				AppendError(validator, errors);
			}
		}
		/// <summary>
		/// Builds the error message to throw when there are validator errors.
		/// </summary>
		/// <param name="method">The method.</param>
		/// <param name="errors">The errors.</param>
		/// <returns></returns>
		protected virtual string BuildErrorMessage(MethodInfo method, ErrorSummary errors)
		{
			StringBuilder builder = new StringBuilder();
			builder.Append(string.Format("Validation failure will invoking method: {0}", method)).Append(Environment.NewLine);
			builder.Append(ErrorSummaryHelper.CreateSummary(errors));
			return builder.ToString();
		}
示例#3
0
		/// <errorSummary>
		/// Determines whether the specified instance is valid.
		/// </errorSummary>
		/// <param name="instance">The instance.</param>
		/// <param name="fieldValue">The field value.</param>
		/// <returns>
		/// 	<c>true</c> if the specified instance is valid; otherwise, <c>false</c>.
		/// </returns>
		public override bool IsValid(object instance, object fieldValue)
		{
			ValidatorRunner runner = new ValidatorRunner(validationRegistry.BaseRegistry);
			bool valid =  runner.IsValid(instance);

			if (!valid)
				errorSummary = runner.GetErrorSummary(instance);

			return valid;
		}
示例#4
0
        public void Validate(ErrorSummary errors)
        {
            if (Product == null)
            {
                errors.RegisterErrorMessage("Product", "The order must have a product.");
                return;
            }

            if (Quantity < Product.MinQuantity || Quantity > Product.MaxQuantity)
                errors.RegisterErrorMessage("Quantity", string.Format("The quantity {0} is invalid, it must be between {1} and {2}", Quantity, Product.MinQuantity, Product.MaxQuantity));
        }
		/// <summary>
		/// Creates a string representation of the error summary.
		/// </summary>
		/// <param name="errors">The errors.</param>
		/// <returns></returns>
		public static string  CreateSummary(ErrorSummary errors)
		{
			StringBuilder builder = new StringBuilder();
			foreach (string property in errors.InvalidProperties)
			{
				builder.Append("    - ").Append(property).Append(": ");
				builder.Append(string.Join(",", errors.GetErrorsForProperty(property)));
				builder.Append(Environment.NewLine);
			}
			return builder.ToString();
		}
		bool IValidationPerformer.PerformValidation(object objectInstance, IEnumerable<IValidator> validators, IEnumerable<IValidationContributor> contributors, RunWhen runWhen, ErrorSummary summaryToPopulate) {
			foreach (IValidator validator in validators) {
				if (!validator.IsValid(objectInstance)) {
					string name = validator.FriendlyName ?? validator.Name;
					summaryToPopulate.RegisterErrorMessage(name, validator.ErrorMessage);
				}
			}

			if(contributors != null)
				(this as IValidationPerformer).ExecuteContributors(objectInstance, contributors, summaryToPopulate, runWhen);

			bool isValid = !summaryToPopulate.HasError;
			return isValid;
		}
 private static string GenerateMessage(ErrorSummary summary)
 {
     StringBuilder sb = new StringBuilder();
     sb.AppendLine("Validation errors");
     foreach (string invalidProperty in summary.InvalidProperties)
     {
         sb.Append(invalidProperty).AppendLine(":");
         foreach (string error in summary.GetErrorsForProperty(invalidProperty))
         {
             sb.Append("\t").AppendLine(error);
         }
         sb.AppendLine();
     }
     return sb.ToString();
 }
		/// <summary>
		/// Determines whether the specified instance is valid.
		/// </summary>
		/// <param name="instance">The instance.</param>
		/// <param name="runWhen">The run when.</param>
		/// <returns></returns>
		public ErrorSummary IsValid(object instance, RunWhen runWhen)
		{
			ErrorSummary errors = new ErrorSummary();

			IInvocation invocation = instance as IInvocation;

			if (invocation == null)
				return errors;

			for (int i = 0; i < invocation.Arguments.Length; i++)
			{
				ValidateParameter(invocation, i, runWhen, errors);
			}

			return errors;
		}
        public void Update([DataBind("details", Validate = true)] UserDetailsRequestDTO details)
        {
            if (Validator.IsValid(details))
            {
                var success = userService.UpdateDetails(details);

                if (!success)
                {
                    var errorSummary = new ErrorSummary();
                    errorSummary.RegisterErrorMessage(string.Empty, "There was a problem updating your details");
                    Flash["errors"] = errorSummary;
                }
            }
            else
                Flash["errors"] = Validator.GetErrorSummary(details);

            RedirectToAction("Show");
        }
        private static void AddModelErrors(ModelStateDictionary modelState, ErrorSummary errorSummary)
        {
            if (errorSummary == null)
            {
                throw new ArgumentNullException("errorSummary");
            }

            var errorInfos = from property in errorSummary.InvalidProperties
                             from message in errorSummary.GetErrorsForProperty(property)
                             select new
                                        {
                                            PropertyName = property,
                                            ErrorMessage = message
                                        };

            foreach (var errorInfo in errorInfos)
            {
                modelState.AddModelError(errorInfo.PropertyName, errorInfo.ErrorMessage);
            }
        }
        public void Should_Fail_To_Send_Email_Because_Email_Is_Invalid()
        {
            // arrange
            const string errorMessage = "message";

            var email = new Email();
            var validatorRunner = new Mock<IValidatorRunner>();
            var errorSummary = new ErrorSummary();

            validatorRunner.Setup(v => v.IsValid(It.IsAny<Email>())).Returns(false);
            validatorRunner.Setup(v => v.GetErrorSummary(It.IsAny<Email>())).Returns(errorSummary);

            errorSummary.RegisterErrorMessage(errorMessage, errorMessage);

            // act
            var service = new EmailSenderService(validatorRunner.Object);

            TestDelegate act = () => service.Send(email);

            // assert
            Assert.That(act, Throws.InstanceOf<ValidationException>().With.Property("ValidationErrorMessages").EqualTo(new[] { errorMessage }));
        }
		/// <summary>
		/// Registers the error message returned from an object validator
		/// as an error message for each individual indexed property.
		/// </summary>
		/// <param name="validator">The validator.</param>
		/// <param name="errors">The errors.</param>
		private void RegisterObjectValidatorErrorMessages(ObjectValidator validator, ErrorSummary errors)
		{
			ErrorSummary objectErrors = validator.ErrorSummary;
			foreach (string property in objectErrors.InvalidProperties)
			{
				foreach (string message in objectErrors.GetErrorsForProperty(property))
				{
					errors.RegisterErrorMessage(validator.FriendlyName + "." + property, message);
				}
			}
		}
		void IValidationPerformer.ExecuteContributors(object objectInstance, IEnumerable<IValidationContributor> contributors, ErrorSummary summaryToPopulate, RunWhen runWhen) {
			foreach (IValidationContributor contributor in contributors) {
				ErrorSummary errors = contributor.IsValid(objectInstance, runWhen);
				summaryToPopulate.RegisterErrorsFrom(errors);
			}
		}
示例#14
0
 /// <summary>
 /// associate error summary to the object instance
 /// </summary>
 /// <param name="objectInstance">object instance to associate validation error summary with</param>
 /// <param name="summary">error summary to be associated with object instance</param>
 protected void SetErrorSummaryForInstance(object objectInstance, ErrorSummary summary)
 {
     errorPerInstance[objectInstance] = summary;
 }
		/// <summary>
		/// Determines whether the specified instance is valid.  Returns an
		/// <see cref="ErrorSummary"/> that will be appended to the existing
		/// error summary for an object.
		/// </summary>
		/// <param name="instance">The instance.</param>
		/// <param name="runWhen">The run when.</param>
		/// <returns></returns>
		protected override ErrorSummary IsValidInternal(object instance, RunWhen runWhen)
		{
			ErrorSummary errorSummary = new ErrorSummary();

			ArrayList methods = (ArrayList)methodsPerType[instance.GetType()];
			
			if (methods == null) return errorSummary;

			foreach (SelfValidationMeta meta in methods)
			{
				if (!IsMetaOnPhase(meta, runWhen)) continue;
				
				MethodInfo methodInfo = meta.MethodInfo;
				methodInfo.Invoke(instance, new object[] {errorSummary});
			}                
			return errorSummary;
		}
		/// <summary>
		/// associate error summary to the object instance
		/// </summary>
		/// <param name="objectInstance">object instance to associate validation error summary with</param>
		/// <param name="summary">error summary to be associated with object instance</param>
		protected void SetErrorSummaryForInstance(object objectInstance, ErrorSummary summary)
		{
			errorPerInstance[objectInstance] = summary;
		}
示例#17
0
		/// <summary>
		/// Registers the errors from another error summary instance.
		/// </summary>
		/// <param name="errorSummary">The error summary.</param>
		public void RegisterErrorsFrom(ErrorSummary errorSummary)
		{
			foreach (string property in errorSummary.InvalidProperties)
			{
				foreach (string errorMessage in errorSummary.GetErrorsForProperty(property))
				{
					RegisterErrorMessage(property, errorMessage);
				}
			}
		}
		/// <summary>
		/// Initializes a new instance of the <see cref="MethodValidationException"/> class.
		/// </summary>
		/// <param name="message">The message.</param>
		/// <param name="errors">The errors.</param>
		public MethodValidationException(string message, ErrorSummary errors) : base(message, errors.ErrorMessages)
		{
			this.errors = errors;
		}
		/// <summary>
		/// Determines whether the specified instance is valid.
		/// <para>
		/// All validators are run for the specified <see cref="RunWhen"/> phase.
		/// </para>
		/// </summary>
		/// <param name="objectInstance">The object instance to be validated (cannot be null).</param>
		/// <param name="runWhen">Restrict the set returned to the phase specified</param>
		/// <returns>
		/// <see langword="true"/> if the specified instance is valid; otherwise, <see langword="false"/>.
		/// </returns>
		public bool IsValid(object objectInstance, RunWhen runWhen)
		{
			if (objectInstance == null) throw new ArgumentNullException("objectInstance");

			bool isValid;
			
			ErrorSummary summary = new ErrorSummary();

			IValidator[] validators = GetValidators(objectInstance, runWhen);
			
			SortValidators(validators);

			isValid = validationPerformer.PerformValidation(
				objectInstance,
				validators,
				contributors,
				runWhen,
				summary);

			SetErrorSummaryForInstance(objectInstance, summary);

			return isValid;
		}
示例#20
0
		protected bool CheckForValidationFailures(object instance, Type instanceType,
		                                          PropertyInfo prop, object value,
		                                          string name, string prefix,
		                                          ErrorSummary summary)
		{
			bool hasFailure = false;

			if (validator == null)
			{
				return false;
			}

			IValidator[] validators = validator.GetValidators(instanceType, prop);

			foreach(IValidator validatorItem in validators)
			{
				if (!validatorItem.IsValid(instance, value))
				{
					string propName = validatorItem.FriendlyName ?? validatorItem.Name;

					errors.Add(new DataBindError(prefix, prop.Name, validatorItem.ErrorMessage));

					summary.RegisterErrorMessage(propName, validatorItem.ErrorMessage);
					
					hasFailure = true;
				}
			}

			return hasFailure;
		}
 /// <summary>
 /// Initializes a new instance of the <see cref="ValidationException"/> class.
 /// </summary>
 /// <param name="errorSummary">The error summary.</param>
 public ValidationException(ErrorSummary errorSummary)
     : base(GenerateMessage(errorSummary))
 {
     this.errorSummary = errorSummary;
 }
示例#22
0
		protected void InternalRecursiveBindObjectInstance(object instance, String prefix, CompositeNode node)
		{
			if (node == null || instance == null)
			{
				return;
			}

			BeforeBinding(instance, prefix, node);

			if (PerformCustomBinding(instance, prefix, node))
			{
				return;
			}

			PushInstance(instance, prefix);

			ErrorSummary summary = new ErrorSummary();

			validationErrorSummaryPerInstance[instance] = summary;

			Type instanceType = instance.GetType();

			PropertyInfo[] props = instanceType.GetProperties(PropertiesBindingFlags);

			string nodeFullName = node.FullName;

			foreach(PropertyInfo prop in props)
			{
				if (ShouldIgnoreProperty(prop, nodeFullName))
				{
					continue;
				}

				Type propType = prop.PropertyType;
				String paramName = prop.Name;

				String translatedParamName = Translate(instanceType, paramName);

				if (translatedParamName == null)
				{
					continue;
				}

				bool isSimpleProperty = IsSimpleProperty(propType);

				// There are some caveats by running the validators here. 
				// We should follow the validator's execution order...
				if (isSimpleProperty)
				{
					if (CheckForValidationFailures(instance, instanceType, prop, node, translatedParamName, prefix, summary))
					{
						continue;
					}
				}

				BeforeBindingProperty(instance, prop, prefix, node);

				try
				{
					bool conversionSucceeded;

					if (isSimpleProperty)
					{
						object value = ConvertToSimpleValue(propType, translatedParamName, node, out conversionSucceeded);

						if (conversionSucceeded)
						{
							SetPropertyValue(instance, prop, value);
						}
					}
					else
					{
						// if the property is an object, we look if it is already instanciated
						object value = prop.GetValue(instance, null);

						Node nestedNode = node.GetChildNode(paramName);

						if (nestedNode != null)
						{
							if (ShouldRecreateInstance(value, propType, paramName, nestedNode))
							{
								value = InternalBindObject(propType, paramName, nestedNode, out conversionSucceeded);

								if (conversionSucceeded)
								{
									SetPropertyValue(instance, prop, value);
								}
							}
							else
							{
								InternalRecursiveBindObjectInstance(value, paramName, nestedNode);
							}
						}

						CheckForValidationFailures(instance, instanceType, prop, value, translatedParamName, prefix, summary);
					}
				}
				catch(Exception ex)
				{
					errors.Add(new DataBindError(prefix, prop.Name, ex));
				}
			}

			PopInstance(instance, prefix);

			AfterBinding(instance, prefix, node);
		}
		/// <summary>
		/// Called when the validator finds an invalid method.
		/// </summary>
		/// <param name="method">The method.</param>
		/// <param name="errors">The errors.</param>
		protected virtual void OnInvalidMethod(MethodInfo method, ErrorSummary errors)
		{
			string errorMessage = BuildErrorMessage(method, errors);
			throw new ValidationException(errorMessage, errors.ErrorMessages);
		}
示例#24
0
 private void CreateErrorMessage(string message)
 {
     var errorSummary = new ErrorSummary();
     errorSummary.RegisterErrorMessage(string.Empty, message);
     Flash["error"] = errorSummary;
 }
示例#25
0
		/// <summary>
		/// Determines whether the specified instance is valid.
		/// <para>
		/// All validators are run for the specified <see cref="RunWhen"/> phase.
		/// </para>
		/// </summary>
		/// <param name="objectInstance">The object instance to be validated (cannot be null).</param>
		/// <param name="runWhen">Restrict the set returned to the phase specified</param>
		/// <returns>
		/// <see langword="true"/> if the specified instance is valid; otherwise, <see langword="false"/>.
		/// </returns>
		public bool IsValid(object objectInstance, RunWhen runWhen)
		{
			if (objectInstance == null) throw new ArgumentNullException("objectInstance");

			bool isValid;

			ErrorSummary summary = new ErrorSummary();

			IEnumerable<IValidator> validators = GetValidators(objectInstance, runWhen);
			
			isValid = PerformValidation(objectInstance, validators, summary);

			return isValid;
		}
示例#26
0
		/// <summary>
		/// main validation logic happens here
		/// </summary>
		/// <param name="objectInstance">object instance to be validated</param>
		/// <param name="validators">the validators to run</param>
		/// <param name="summaryToPopulate"></param>
		protected virtual bool PerformValidation(object objectInstance, IEnumerable<IValidator> validators, ErrorSummary summaryToPopulate) 
		{
			bool isValid = true;

			foreach (IValidator validator in validators) {
				if (!validator.IsValid(objectInstance)) {
					string name = validator.FriendlyName ?? validator.Name;

					summaryToPopulate.RegisterErrorMessage(name, validator.ErrorMessage);

					isValid = false;
				}
			}

			SetErrorSummaryForInstance(objectInstance, summaryToPopulate);

			return isValid;
		}
示例#27
0
		protected bool CheckForValidationFailures(object instance, Type instanceType,
		                                          PropertyInfo prop, CompositeNode node,
		                                          string name, string prefix,
		                                          ErrorSummary summary)
		{
			object value = null;

			if (validator == null)
			{
				return false;
			}

			IValidator[] validators = validator.GetValidators(instanceType, prop);

			if (validators.Length != 0)
			{
				Node valNode = node.GetChildNode(name);

				if (valNode != null && valNode.NodeType == NodeType.Leaf)
				{
					value = ((LeafNode)valNode).Value;
				}

				if (value == null && IsDateTimeType(prop.PropertyType))
				{
					bool conversionSucceeded;
					value = TryGetDateWithUTCFormat(node, name, out conversionSucceeded);
				}

				if (value == null && valNode == null)
				{
					// Value was not present on the data source. Skip validation
					return false;
				}
			}

			return CheckForValidationFailures(instance, instanceType, prop, value, name, prefix, summary);
		}
		/// <summary>
		/// Appends the error to the <see cref="ErrorSummary">ErrorSummary</see>.
		/// </summary>
		/// <param name="validator">The validator.</param>
		/// <param name="errors">The errors.</param>
		protected virtual void AppendError(IValidator validator, ErrorSummary errors)
		{
			string name = validator.FriendlyName ?? validator.Name;

			ObjectValidator objectValidator = validator as ObjectValidator;
			if (objectValidator != null)
				RegisterObjectValidatorErrorMessages(objectValidator, errors);
			else 
				errors.RegisterErrorMessage(name, validator.ErrorMessage);
		}
示例#29
0
        bool IValidationPerformer.PerformValidation(object objectInstance, IEnumerable <IValidator> validators, IEnumerable <IValidationContributor> contributors, RunWhen runWhen, ErrorSummary summaryToPopulate)
        {
            foreach (IValidator validator in validators)
            {
                if (!validator.IsValid(objectInstance))
                {
                    string name = validator.FriendlyName ?? validator.Name;
                    summaryToPopulate.RegisterErrorMessage(name, validator.ErrorMessage);
                }
            }

            if (contributors != null)
            {
                (this as IValidationPerformer).ExecuteContributors(objectInstance, contributors, summaryToPopulate, runWhen);
            }

            bool isValid = !summaryToPopulate.HasError;

            return(isValid);
        }
示例#30
0
 void IValidationPerformer.ExecuteContributors(object objectInstance, IEnumerable <IValidationContributor> contributors, ErrorSummary summaryToPopulate, RunWhen runWhen)
 {
     foreach (IValidationContributor contributor in contributors)
     {
         ErrorSummary errors = contributor.IsValid(objectInstance, runWhen);
         summaryToPopulate.RegisterErrorsFrom(errors);
     }
 }
示例#31
0
		/// <summary>
		/// Populates the validator error summary with errors relative to the
		/// validation rules associated with the target type.
		/// </summary>
		/// <param name="instance">The instance.</param>
		/// <param name="binderUsedForBinding">The binder used for binding.</param>
		public void PopulateValidatorErrorSummary(object instance, ErrorSummary binderUsedForBinding)
		{
			if (validationSummaryPerInstance == null)
			{
				validationSummaryPerInstance = new Dictionary<object, ErrorSummary>();
			}
			validationSummaryPerInstance[instance] = binderUsedForBinding;
		}
		/// <summary>
		/// Validate method parameters that are decorated with the params keyword.
		/// </summary>
		/// <param name="validator">The validator.</param>
		/// <param name="propertyAccessAware">The property access aware.</param>
		/// <param name="value">The value.</param>
		/// <param name="errors">The errors.</param>
		private void ValidateParamsArray(IValidator validator, IPropertyAccessAware propertyAccessAware, object value, ErrorSummary errors)
		{
			object[] paramsValue = (object[]) value;
			foreach (object paramValue in paramsValue)
			{
				propertyAccessAware.PropertyAccessor = delegate { return paramValue; };
				if (validator.IsValid(paramValue)) continue;
				AppendError(validator, errors);
			}
		}