internal static bool ValidateMethodCall(string methodName,
                                                ValidationContext validationContext, object[] parameters,
                                                List <ValidationResult> validationResults, bool performTypeValidation)
        {
            if (string.IsNullOrEmpty(methodName))
            {
                throw new ArgumentNullException("methodName");
            }

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

            if (validationContext.ObjectInstance == null)
            {
                throw new ArgumentException(DataResource.ValidationUtilities_ContextInstance_CannotBeNull, "validationContext");
            }

            MethodInfo        method        = GetMethod(validationContext.ObjectInstance, methodName, parameters);
            ValidationContext methodContext = CreateValidationContext(validationContext.ObjectInstance, validationContext);

            methodContext.MemberName = method.Name;

            DisplayAttribute display = GetDisplayAttribute(method);

            if (display != null)
            {
                methodContext.DisplayName = display.GetName();
            }

            string memberPath = string.Empty;

            if (performTypeValidation)
            {
                memberPath = method.Name + ".";
            }

            IEnumerable <ValidationAttribute> validationAttributes = method.GetCustomAttributes(typeof(ValidationAttribute), true).Cast <ValidationAttribute>();
            bool success = ValidationUtilities.ValidateValue(validationContext.ObjectInstance, methodContext, validationResults, validationAttributes, string.Empty);

            ParameterInfo[] parameterInfos = method.GetParameters();

            for (int paramIndex = 0; paramIndex < parameterInfos.Length; paramIndex++)
            {
                ParameterInfo methodParameter = parameterInfos[paramIndex];
                object        value           = (parameters.Length > paramIndex ? parameters[paramIndex] : null);

                ValidationContext parameterContext = ValidationUtilities.CreateValidationContext(validationContext.ObjectInstance, validationContext);
                parameterContext.MemberName = methodParameter.Name;

                string paramName = methodParameter.Name;

                display = GetDisplayAttribute(methodParameter);

                if (display != null)
                {
                    paramName = display.GetName();
                }

                parameterContext.DisplayName = paramName;

                string parameterPath = memberPath;
                if (performTypeValidation)
                {
                    parameterPath += methodParameter.Name;
                }

                IEnumerable <ValidationAttribute> parameterAttributes = methodParameter.GetCustomAttributes(typeof(ValidationAttribute), false).Cast <ValidationAttribute>();
                bool parameterSuccess = ValidationUtilities.ValidateValue(value, parameterContext, validationResults,
                                                                          parameterAttributes, ValidationUtilities.NormalizeMemberPath(parameterPath, methodParameter.ParameterType));

                if (parameterSuccess && performTypeValidation && value != null)
                {
                    Type parameterType = methodParameter.ParameterType;

                    // If the user expects an exception we perform shallow validation only.
                    if (validationResults == null)
                    {
                        if (TypeUtility.IsComplexType(parameterType))
                        {
                            ValidationContext context = ValidationUtilities.CreateValidationContext(value, parameterContext);
                            context.DisplayName = paramName;
                            Validator.ValidateObject(value, context, /*validateAllProperties*/ true);
                        }
                    }
                    // Else we are able to report fully recursive validation errors to the user, perform deep validation.
                    else
                    {
                        if (TypeUtility.IsComplexType(parameterType))
                        {
                            parameterSuccess = ValidationUtilities.ValidateObjectRecursive(value, parameterPath, validationContext, validationResults);
                        }
                        else if (TypeUtility.IsComplexTypeCollection(parameterType))
                        {
                            parameterSuccess = ValidationUtilities.ValidateComplexCollection(value as IEnumerable, parameterPath, validationContext, validationResults);
                        }
                    }
                }

                success &= parameterSuccess;
            }

            return(success);
        }
        internal static bool TryValidateMethodCall(DomainOperationEntry operationEntry, ValidationContext validationContext, object[] parameters, List <ValidationResult> validationResults)
        {
            bool breakOnFirstError = validationResults == null;

            ValidationContext methodContext = CreateValidationContext(validationContext.ObjectInstance, validationContext);

            methodContext.MemberName = operationEntry.Name;

            DisplayAttribute display = (DisplayAttribute)operationEntry.Attributes[typeof(DisplayAttribute)];

            if (display != null)
            {
                methodContext.DisplayName = display.GetName();
            }

            string methodPath = string.Empty;

            if (operationEntry.Operation == DomainOperation.Custom)
            {
                methodPath = operationEntry.Name + ".";
            }

            IEnumerable <ValidationAttribute> validationAttributes = operationEntry.Attributes.OfType <ValidationAttribute>();
            bool success = Validator.TryValidateValue(validationContext.ObjectInstance, methodContext, validationResults, validationAttributes);

            if (!breakOnFirstError || success)
            {
                for (int paramIndex = 0; paramIndex < operationEntry.Parameters.Count; paramIndex++)
                {
                    DomainOperationParameter methodParameter = operationEntry.Parameters[paramIndex];
                    object value = (parameters.Length > paramIndex ? parameters[paramIndex] : null);

                    ValidationContext parameterContext = ValidationUtilities.CreateValidationContext(validationContext.ObjectInstance, validationContext);
                    parameterContext.MemberName = methodParameter.Name;

                    string paramName = methodParameter.Name;

                    AttributeCollection parameterAttributes = methodParameter.Attributes;
                    display = (DisplayAttribute)parameterAttributes[typeof(DisplayAttribute)];

                    if (display != null)
                    {
                        paramName = display.GetName();
                    }

                    parameterContext.DisplayName = paramName;

                    string parameterPath = string.Empty;
                    if (!string.IsNullOrEmpty(methodPath) && paramIndex > 0)
                    {
                        parameterPath = methodPath + methodParameter.Name;
                    }

                    IEnumerable <ValidationAttribute> parameterValidationAttributes = parameterAttributes.OfType <ValidationAttribute>();
                    bool parameterSuccess = ValidationUtilities.ValidateValue(value, parameterContext, validationResults, parameterValidationAttributes,
                                                                              ValidationUtilities.NormalizeMemberPath(parameterPath, methodParameter.ParameterType));

                    // Custom methods run deep validation as well as parameter validation.
                    // If parameter validation has already failed, stop further validation.
                    if (parameterSuccess && operationEntry.Operation == DomainOperation.Custom && value != null)
                    {
                        Type parameterType = methodParameter.ParameterType;

                        if (TypeUtility.IsComplexType(parameterType))
                        {
                            parameterSuccess = ValidationUtilities.ValidateObjectRecursive(value, parameterPath, parameterContext, validationResults);
                        }
                        else if (TypeUtility.IsComplexTypeCollection(parameterType))
                        {
                            parameterSuccess = ValidationUtilities.ValidateComplexCollection(value as IEnumerable, parameterPath, parameterContext, validationResults);
                        }
                    }

                    success &= parameterSuccess;

                    if (breakOnFirstError && !success)
                    {
                        break;
                    }
                }
            }

            return(success);
        }