public string GetErrorMessage(IErrorResolver resolver, string propertyName, object value)
        {
            if (resolver == null)
            {
                throw new ArgumentNullException("resolver");
            }

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

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

            var exp = this.CreatePropertyExpression(propertyName, value);

            ValidationError[] validationErrors;
            if (this.HasError(exp, value, out validationErrors))
            {
                return(resolver.GetErrorMessage(validationErrors[0]));
            }

            return(null);
        }
        public string[] GetErrorMessages(object value, IErrorResolver errorResolver)
        {
            if (errorResolver == null)
            {
                throw new System.ArgumentNullException("errorResolver");
            }
            if (value == null)
            {
                throw new System.ArgumentNullException("value");
            }
            var result = new List <string>();
            Dictionary <EquatableExpression, List <ValidationError> > errorsOnValue;

            if (!_errors.TryGetValue(value, out errorsOnValue))
            {
                return(new string[0]);
            }
            foreach (var expression in errorsOnValue.Keys)
            {
                foreach (var errorOnExpression in errorsOnValue[expression])
                {
                    var message = errorResolver.GetErrorMessage(errorOnExpression.Value.GetType(), errorOnExpression.Expression, errorOnExpression.Rule, errorOnExpression.ValidationArguments);
                    if (message == null)
                    {
                        continue;
                    }
                    result.Add(message);
                }
            }
            return(result.ToArray());
        }
        public string GetErrorMessage(IErrorResolver resolver, string propertyName, object value)
        {
            if (resolver == null) throw new System.ArgumentNullException("resolver");
            if (value == null) throw new System.ArgumentNullException("value");
            if (propertyName == null) throw new System.ArgumentNullException("propertyName");
            var exp = CreatePropertyExpression(propertyName, value);

            ValidationError[] validationErrors;

            if (base.HasError(exp, value, out validationErrors))
            {
                return resolver.GetErrorMessage(validationErrors[0]);
            }

            return null;
        }
        public string GetErrorMessage(object value, EquatableExpression expression, IErrorResolver resolver)
        {
            //NOTE: Expression can be null.
            if (value == null)
            {
                throw new System.ArgumentNullException("value");
            }
            if (resolver == null)
            {
                throw new System.ArgumentNullException("resolver");
            }

            ValidationError[] errors;
            ValidationError   error;

            object[] validationArguments = new object[0];

            if (this.HasError(value, expression, out errors))
            {
                error = errors[0];
                validationArguments = error.ValidationArguments;
                var message = resolver.GetErrorMessage(error.Value.GetType(), error.Expression, error.Rule, error.ValidationArguments);
                return(message);
            }
            else if (expression != null && expression.Expression.ReturnType.IsClass && expression.Expression.ReturnType != typeof(string))
            {
                //There may be the case that for compositions, a message is set for CallValidate(). When
                //this happens, there won't be any error for a => a.C (where 'C' is another object)
                //still, you would like to have a 'C is not valid' message...

                //Step 1: find out if there are any Messages defined for that property
                var message = resolver.GetErrorMessage(value.GetType(), expression, null, new object[0]);
                //if null fallback on message for the type of that property.
                if (message == null)
                {
                    message = resolver.GetErrorMessage(expression.Expression.ReturnType, null, null, new object[0]);
                }
                if (message == null)
                {
                    return(null);
                }

                //Step 2: There is a Message defined. Find out if there is an error for the property.
                object propertyValue = null;
                try
                {
                    //TODO: This should be resolved using a Interface maybe.
                    propertyValue = expression.Expression.Compile().DynamicInvoke(value);
                }
                catch (NullReferenceException)
                {
                    //NOTE: Swallow all NullReferenceException.
                }
                catch (Exception ex)
                {
                    //Wrap and re-throw.
                    throw new InvalidOperationException(string.Format("Could not get property value for expression {0}. See InnerException for details.", expression.Expression), ex);
                }
                if (propertyValue == null)
                {
                    return(null);
                }

                //Step 3: The property may be an IEnumerable. Need to return the message if any elements has an error...
                //TODO: This is bit dodgy, you should only enumerate if a CallValidateForEach was used...
                //Return null if none of the propertyValue(s) have errors.
                if (ToEnumerable(propertyValue).All(v => !HasError(v, null)))
                {
                    return(null);
                }
                return(message);
            }

            return(null);
        }