private void GetValidationsForDto(GetValidationsParms parms)
        {
            parms.JsonString.Append(parms.JsonObjectName + ": { ");

            var dtoClass = TypeHelper.GetObjectType(parms.DtoObjectName, false, parms.DtoAlternateNamespace, parms.DtoAssemblyNames.ToArray());

            if (dtoClass == null)
            {
                var message = string.Format("DTO '{0}' not found.", parms.DtoObjectName);
                throw new Exception(message);
            }

            var properties = dtoClass.GetProperties();

            if (properties != null)
            {
                var isFirstProp = true;

                DealWithProperties(properties, ref parms, ref isFirstProp);

                MetadataTypeAttribute[] metadataTypes = dtoClass.GetCustomAttributes(typeof(MetadataTypeAttribute), true).OfType <MetadataTypeAttribute>().ToArray();
                MetadataTypeAttribute   metadata      = metadataTypes.FirstOrDefault();

                if (metadata != null)
                {
                    properties = metadata.MetadataClassType.GetProperties();
                    if (properties != null)
                    {
                        DealWithProperties(properties, ref parms, ref isFirstProp);
                    }
                }
            }

            parms.JsonString.Append("}");
        }
        public void Init()
        {
            _parms = new GetValidationsParms("TestDTO.ValidationTest", "model")
            {
                DtoAssemblyNames = new List <string> {
                    "Intertech.Validation.Test"
                },
                ResourceAssemblyName = "Intertech.Validation.Test",
                ResourceNamespace    = "Intertech.Validation.Test.TestDTO"
            };

            var vals = new StringBuilder("{ validations: { model: { ");

            vals.Append("Name: { \"ng-minlength\": 3, \"ng-minlength-msg\": \"" + string.Format(DataAnnotationConstants.DefaultMinLengthErrorMsg, "Name", "3") + "\", \"required\": true, \"required-msg\": \"" + TestResource.NameRequiredResource + "\" }");
            vals.Append(", CreditCard: { \"ng-pattern\": \"/" + RegexConstants.GetRegularExpressionForJson(RegexConstants.CreditCard) + "/\", \"ng-pattern-msg\": \"" + string.Format(DataAnnotationConstants.DefaultCreditCardErrorMsg, "CreditCard") + "\" }");
            vals.Append(", Email: { \"ng-pattern\": \"/" + RegexConstants.GetRegularExpressionForJson(RegexConstants.Email) + "/\", \"ng-pattern-msg\": \"" + string.Format(DataAnnotationConstants.DefaultEmailErrorMsg, "Email") + "\" }");
            vals.Append(", Email2: { \"ng-pattern\": \"/" + RegexConstants.GetRegularExpressionForJson(RegexConstants.Email) + "/\", \"ng-pattern-msg\": \"" + ErrorMessages.Email + "\" }");
            vals.Append(", Street: { \"ng-maxlength\": 40, \"ng-maxlength-msg\": \"" + string.Format(DataAnnotationConstants.DefaultMaxLengthErrorMsg, "Street", "40") + "\" }");
            vals.Append(", Phone: { \"ng-pattern\": \"/" + RegexConstants.GetRegularExpressionForJson(RegexConstants.Phone) + "/\", \"ng-pattern-msg\": \"" + string.Format(DataAnnotationConstants.DefaultPhoneErrorMsg, "Phone") + "\" }");
            vals.Append(", Phone2: { \"ng-pattern\": \"/" + RegexConstants.GetRegularExpressionForJson(RegexConstants.Phone) + "/\", \"ng-pattern-msg\": \"" + ErrorMessages.Phone + "\" }");
            vals.Append(", FavoriteNumber: { \"min\": 1, \"min-msg\": \"" + string.Format(DataAnnotationConstants.DefaultRangeErrorMsg, "FavoriteNumber", "1", "100") + "\", \"max\": 100, \"max-msg\": \"" + string.Format(DataAnnotationConstants.DefaultRangeErrorMsg, "FavoriteNumber", "1", "100") + "\" }");
            vals.Append(", IntegerString: { \"ng-pattern\": \"/" + RegexConstants.GetRegularExpressionForJson(RegexConstants.Integer) + "/\", \"ng-pattern-msg\": \"" + string.Format(DataAnnotationConstants.DefaultRegexErrorMsg, "IntegerString") + "\" }");
            vals.Append(", DecimalString: { \"ng-pattern\": \"/" + RegexConstants.GetRegularExpressionForJson(RegexConstants.Decimal) + "/\", \"ng-pattern-msg\": \"" + ErrorMessages.Regex + "\" }");
            vals.Append(", NickName: { \"ng-maxlength\": 30, \"ng-maxlength-msg\": \"" + string.Format(DataAnnotationConstants.DefaultMaxLengthErrorMsg, "Nick Name", "30") + "\", \"ng-minlength\": 2, \"ng-minlength-msg\": \"" + string.Format(DataAnnotationConstants.DefaultMinLengthErrorMsg, "Nick Name", "2") + "\" }");
            vals.Append(", Website: { \"ng-pattern\": \"/" + RegexConstants.GetRegularExpressionForJson(RegexConstants.Url) + "/\", \"ng-pattern-msg\": \"" + string.Format(DataAnnotationConstants.DefaultUrlErrorMsg, "Website") + "\" }");
            vals.Append(", Length: { \"ng-minlength\": 5, \"ng-minlength-msg\": \"" + ErrorMessages.MinLength + "\", \"ng-maxlength\": 25, \"ng-maxlength-msg\": \"" + ErrorMessages.MaxLength + "\", \"required\": true, \"required-msg\": \"" + ErrorMessages.Required + "\" }");
            vals.Append(", Visa: { \"ng-pattern\": \"/" + RegexConstants.GetRegularExpressionForJson(RegexConstants.CreditCard) + "/\", \"ng-pattern-msg\": \"" + ErrorMessages.CreditCard + "\", \"ng-maxlength\": 30, \"ng-maxlength-msg\": \"" + ErrorMessages.VisaLength + "\", \"ng-minlength\": 12, \"ng-minlength-msg\": \"" + ErrorMessages.VisaLength + "\" }");
            vals.Append(", Url: { \"ng-pattern\": \"/" + RegexConstants.GetRegularExpressionForJson(RegexConstants.Url) + "/\", \"ng-pattern-msg\": \"" + ErrorMessages.Url + "\" }");
            vals.Append(" }");
            vals.Append("} }");
            _validations = JObject.Parse(vals.ToString());


            var valsCC = new StringBuilder("{ validations: { model: { ");

            valsCC.Append("name: { \"ng-minlength\": 3, \"ng-minlength-msg\": \"" + string.Format(DataAnnotationConstants.DefaultMinLengthErrorMsg, "Name", "3") + "\", \"required\": true, \"required-msg\": \"" + string.Format(DataAnnotationConstants.DefaultRequiredErrorMsg, "Name") + "\" }");
            valsCC.Append(", creditCard: { \"ng-pattern\": \"/" + RegexConstants.GetRegularExpressionForJson(RegexConstants.CreditCard) + "/\", \"ng-pattern-msg\": \"" + string.Format(DataAnnotationConstants.DefaultCreditCardErrorMsg, "CreditCard") + "\" }");
            valsCC.Append(", email: { \"ng-pattern\": \"/" + RegexConstants.GetRegularExpressionForJson(RegexConstants.Email) + "/\", \"ng-pattern-msg\": \"" + string.Format(DataAnnotationConstants.DefaultEmailErrorMsg, "Email") + "\" }");
            valsCC.Append(", email2: { \"ng-pattern\": \"/" + RegexConstants.GetRegularExpressionForJson(RegexConstants.Email) + "/\", \"ng-pattern-msg\": \"" + ErrorMessages.Email + "\" }");
            valsCC.Append(", street: { \"ng-maxlength\": 40, \"ng-maxlength-msg\": \"" + string.Format(DataAnnotationConstants.DefaultMaxLengthErrorMsg, "Street", "40") + "\" }");
            valsCC.Append(", phone: { \"ng-pattern\": \"/" + RegexConstants.GetRegularExpressionForJson(RegexConstants.Phone) + "/\", \"ng-pattern-msg\": \"" + string.Format(DataAnnotationConstants.DefaultPhoneErrorMsg, "Phone") + "\" }");
            valsCC.Append(", phone2: { \"ng-pattern\": \"/" + RegexConstants.GetRegularExpressionForJson(RegexConstants.Phone) + "/\", \"ng-pattern-msg\": \"" + ErrorMessages.Phone + "\" }");
            valsCC.Append(", favoriteNumber: { \"min\": 1, \"min-msg\": \"" + string.Format(DataAnnotationConstants.DefaultRangeErrorMsg, "FavoriteNumber", "1", "100") + "\", \"max\": 100, \"max-msg\": \"" + string.Format(DataAnnotationConstants.DefaultRangeErrorMsg, "FavoriteNumber", "1", "100") + "\" }");
            valsCC.Append(", integerString: { \"ng-pattern\": \"/" + RegexConstants.GetRegularExpressionForJson(RegexConstants.Integer) + "/\", \"ng-pattern-msg\": \"" + string.Format(DataAnnotationConstants.DefaultRegexErrorMsg, "IntegerString") + "\" }");
            valsCC.Append(", decimalString: { \"ng-pattern\": \"/" + RegexConstants.GetRegularExpressionForJson(RegexConstants.Decimal) + "/\", \"ng-pattern-msg\": \"" + ErrorMessages.Regex + "\" }");
            valsCC.Append(", nickName: { \"ng-maxlength\": 30, \"ng-maxlength-msg\": \"" + string.Format(DataAnnotationConstants.DefaultMaxLengthErrorMsg, "Nick Name", "30") + "\", \"ng-minlength\": 2, \"ng-minlength-msg\": \"" + string.Format(DataAnnotationConstants.DefaultMinLengthErrorMsg, "Nick Name", "2") + "\" }");
            valsCC.Append(", website: { \"ng-pattern\": \"/" + RegexConstants.GetRegularExpressionForJson(RegexConstants.Url) + "/\", \"ng-pattern-msg\": \"" + string.Format(DataAnnotationConstants.DefaultUrlErrorMsg, "Website") + "\" }");
            valsCC.Append(", length: { \"ng-minlength\": 5, \"ng-minlength-msg\": \"" + ErrorMessages.MinLength + "\", \"ng-maxlength\": 25, \"ng-maxlength-msg\": \"" + ErrorMessages.MaxLength + "\", \"required\": true, \"required-msg\": \"" + ErrorMessages.Required + "\" }");
            valsCC.Append(", visa: { \"ng-pattern\": \"/" + RegexConstants.GetRegularExpressionForJson(RegexConstants.CreditCard) + "/\", \"ng-pattern-msg\": \"" + ErrorMessages.CreditCard + "\", \"ng-maxlength\": 30, \"ng-maxlength-msg\": \"" + ErrorMessages.VisaLength + "\", \"ng-minlength\": 12, \"ng-minlength-msg\": \"" + ErrorMessages.VisaLength + "\" }");
            valsCC.Append(", url: { \"ng-pattern\": \"/" + RegexConstants.GetRegularExpressionForJson(RegexConstants.Url) + "/\", \"ng-pattern-msg\": \"" + ErrorMessages.Url + "\" }");
            valsCC.Append(" }");
            valsCC.Append("} }");
            _validationsCC = JObject.Parse(valsCC.ToString());



            _emptyValidations = JObject.Parse("{ validations: { model: { } } }");
        }
        /// <summary>
        /// Get the validations for dtoObjectName and return the json object.
        /// </summary>
        /// <param name="dtoObjectName"></param>
        /// <param name="jsonObjectName"></param>
        /// <param name="assemblyNames">Names of assemblies to check</param>
        /// <returns></returns>
        public object GetValidations(string dtoObjectName, string jsonObjectName, string alternateNamespace, bool useCamelCaseForProperties, params string[] assemblyNames)
        {
            var parms = new GetValidationsParms(dtoObjectName, jsonObjectName)
            {
                DtoAlternateNamespace     = alternateNamespace,
                DtoAssemblyNames          = new List <string>(assemblyNames),
                UseCamelCaseForProperties = useCamelCaseForProperties
            };

            return(GetValidations(parms));
        }
        /// <summary>
        /// Get the validations for the given parms.
        /// </summary>
        /// <param name="parms"></param>
        /// <returns></returns>
        public object GetValidations(GetValidationsParms parms)
        {
            if (parms == null)
            {
                throw new ArgumentNullException("parms", "Expecting GetValidationParms in GetValidations call and they were not supplied.");
            }

            GetValidationsForDto(parms);

            parms.CompleteJsonString();

            return(JObject.Parse(parms.JsonString.ToString()));
        }
        public void Init()
        {
            _parms = new GetValidationsParms("TestDTO.ValidationTest", "model")
            {
                DtoAssemblyNames = new List<string> { "Intertech.Validation.Test" },
                ResourceAssemblyName = "Intertech.Validation.Test",
                ResourceNamespace = "Intertech.Validation.Test.TestDTO"
            };

            var vals = new StringBuilder("{ validations: { model: { ");
            vals.Append("Name: { \"ng-minlength\": 3, \"ng-minlength-msg\": \"" + string.Format(DataAnnotationConstants.DefaultMinLengthErrorMsg, "Name", "3") + "\", \"required\": true, \"required-msg\": \"" + TestResource.NameRequiredResource + "\" }");
            vals.Append(", CreditCard: { \"ng-pattern\": \"/" + RegexConstants.GetRegularExpressionForJson(RegexConstants.CreditCard) + "/\", \"ng-pattern-msg\": \"" + string.Format(DataAnnotationConstants.DefaultCreditCardErrorMsg, "CreditCard") + "\" }");
            vals.Append(", Email: { \"ng-pattern\": \"/" + RegexConstants.GetRegularExpressionForJson(RegexConstants.Email) + "/\", \"ng-pattern-msg\": \"" + string.Format(DataAnnotationConstants.DefaultEmailErrorMsg, "Email") + "\" }");
            vals.Append(", Email2: { \"ng-pattern\": \"/" + RegexConstants.GetRegularExpressionForJson(RegexConstants.Email) + "/\", \"ng-pattern-msg\": \"" + ErrorMessages.Email + "\" }");
            vals.Append(", Street: { \"ng-maxlength\": 40, \"ng-maxlength-msg\": \"" + string.Format(DataAnnotationConstants.DefaultMaxLengthErrorMsg, "Street", "40") + "\" }");
            vals.Append(", Phone: { \"ng-pattern\": \"/" + RegexConstants.GetRegularExpressionForJson(RegexConstants.Phone) + "/\", \"ng-pattern-msg\": \"" + string.Format(DataAnnotationConstants.DefaultPhoneErrorMsg, "Phone") + "\" }");
            vals.Append(", Phone2: { \"ng-pattern\": \"/" + RegexConstants.GetRegularExpressionForJson(RegexConstants.Phone) + "/\", \"ng-pattern-msg\": \"" + ErrorMessages.Phone + "\" }");
            vals.Append(", FavoriteNumber: { \"min\": 1, \"min-msg\": \"" + string.Format(DataAnnotationConstants.DefaultRangeErrorMsg, "FavoriteNumber", "1", "100") + "\", \"max\": 100, \"max-msg\": \"" + string.Format(DataAnnotationConstants.DefaultRangeErrorMsg, "FavoriteNumber", "1", "100") + "\" }");
            vals.Append(", IntegerString: { \"ng-pattern\": \"/" + RegexConstants.GetRegularExpressionForJson(RegexConstants.Integer) + "/\", \"ng-pattern-msg\": \"" + string.Format(DataAnnotationConstants.DefaultRegexErrorMsg, "IntegerString") + "\" }");
            vals.Append(", DecimalString: { \"ng-pattern\": \"/" + RegexConstants.GetRegularExpressionForJson(RegexConstants.Decimal) + "/\", \"ng-pattern-msg\": \"" + ErrorMessages.Regex + "\" }");
            vals.Append(", NickName: { \"ng-maxlength\": 30, \"ng-maxlength-msg\": \"" + string.Format(DataAnnotationConstants.DefaultMaxLengthErrorMsg, "NickName", "30") + "\", \"ng-minlength\": 2, \"ng-minlength-msg\": \"" + string.Format(DataAnnotationConstants.DefaultMinLengthErrorMsg, "NickName", "2") + "\" }");
            vals.Append(", Website: { \"ng-pattern\": \"/" + RegexConstants.GetRegularExpressionForJson(RegexConstants.Url) + "/\", \"ng-pattern-msg\": \"" + string.Format(DataAnnotationConstants.DefaultUrlErrorMsg, "Website") + "\" }");
            vals.Append(", Length: { \"ng-minlength\": 5, \"ng-minlength-msg\": \"" + ErrorMessages.MinLength + "\", \"ng-maxlength\": 25, \"ng-maxlength-msg\": \"" + ErrorMessages.MaxLength + "\", \"required\": true, \"required-msg\": \"" + ErrorMessages.Required + "\" }");
            vals.Append(", Visa: { \"ng-pattern\": \"/" + RegexConstants.GetRegularExpressionForJson(RegexConstants.CreditCard) + "/\", \"ng-pattern-msg\": \"" + ErrorMessages.CreditCard + "\", \"ng-maxlength\": 30, \"ng-maxlength-msg\": \"" + ErrorMessages.VisaLength + "\", \"ng-minlength\": 12, \"ng-minlength-msg\": \"" + ErrorMessages.VisaLength + "\" }");
            vals.Append(", Url: { \"ng-pattern\": \"/" + RegexConstants.GetRegularExpressionForJson(RegexConstants.Url) + "/\", \"ng-pattern-msg\": \"" + ErrorMessages.Url + "\" }");
            vals.Append(" }");
            vals.Append("} }");
            _validations = JObject.Parse(vals.ToString());

            var valsCC = new StringBuilder("{ validations: { model: { ");
            valsCC.Append("name: { \"ng-minlength\": 3, \"ng-minlength-msg\": \"" + string.Format(DataAnnotationConstants.DefaultMinLengthErrorMsg, "Name", "3") + "\", \"required\": true, \"required-msg\": \"" + string.Format(DataAnnotationConstants.DefaultRequiredErrorMsg, "Name") + "\" }");
            valsCC.Append(", creditCard: { \"ng-pattern\": \"/" + RegexConstants.GetRegularExpressionForJson(RegexConstants.CreditCard) + "/\", \"ng-pattern-msg\": \"" + string.Format(DataAnnotationConstants.DefaultCreditCardErrorMsg, "CreditCard") + "\" }");
            valsCC.Append(", email: { \"ng-pattern\": \"/" + RegexConstants.GetRegularExpressionForJson(RegexConstants.Email) + "/\", \"ng-pattern-msg\": \"" + string.Format(DataAnnotationConstants.DefaultEmailErrorMsg, "Email") + "\" }");
            valsCC.Append(", email2: { \"ng-pattern\": \"/" + RegexConstants.GetRegularExpressionForJson(RegexConstants.Email) + "/\", \"ng-pattern-msg\": \"" + ErrorMessages.Email + "\" }");
            valsCC.Append(", street: { \"ng-maxlength\": 40, \"ng-maxlength-msg\": \"" + string.Format(DataAnnotationConstants.DefaultMaxLengthErrorMsg, "Street", "40") + "\" }");
            valsCC.Append(", phone: { \"ng-pattern\": \"/" + RegexConstants.GetRegularExpressionForJson(RegexConstants.Phone) + "/\", \"ng-pattern-msg\": \"" + string.Format(DataAnnotationConstants.DefaultPhoneErrorMsg, "Phone") + "\" }");
            valsCC.Append(", phone2: { \"ng-pattern\": \"/" + RegexConstants.GetRegularExpressionForJson(RegexConstants.Phone) + "/\", \"ng-pattern-msg\": \"" + ErrorMessages.Phone + "\" }");
            valsCC.Append(", favoriteNumber: { \"min\": 1, \"min-msg\": \"" + string.Format(DataAnnotationConstants.DefaultRangeErrorMsg, "FavoriteNumber", "1", "100") + "\", \"max\": 100, \"max-msg\": \"" + string.Format(DataAnnotationConstants.DefaultRangeErrorMsg, "FavoriteNumber", "1", "100") + "\" }");
            valsCC.Append(", integerString: { \"ng-pattern\": \"/" + RegexConstants.GetRegularExpressionForJson(RegexConstants.Integer) + "/\", \"ng-pattern-msg\": \"" + string.Format(DataAnnotationConstants.DefaultRegexErrorMsg, "IntegerString") + "\" }");
            valsCC.Append(", decimalString: { \"ng-pattern\": \"/" + RegexConstants.GetRegularExpressionForJson(RegexConstants.Decimal) + "/\", \"ng-pattern-msg\": \"" + ErrorMessages.Regex + "\" }");
            valsCC.Append(", nickName: { \"ng-maxlength\": 30, \"ng-maxlength-msg\": \"" + string.Format(DataAnnotationConstants.DefaultMaxLengthErrorMsg, "NickName", "30") + "\", \"ng-minlength\": 2, \"ng-minlength-msg\": \"" + string.Format(DataAnnotationConstants.DefaultMinLengthErrorMsg, "NickName", "2") + "\" }");
            valsCC.Append(", website: { \"ng-pattern\": \"/" + RegexConstants.GetRegularExpressionForJson(RegexConstants.Url) + "/\", \"ng-pattern-msg\": \"" + string.Format(DataAnnotationConstants.DefaultUrlErrorMsg, "Website") + "\" }");
            valsCC.Append(", length: { \"ng-minlength\": 5, \"ng-minlength-msg\": \"" + ErrorMessages.MinLength + "\", \"ng-maxlength\": 25, \"ng-maxlength-msg\": \"" + ErrorMessages.MaxLength + "\", \"required\": true, \"required-msg\": \"" + ErrorMessages.Required + "\" }");
            valsCC.Append(", visa: { \"ng-pattern\": \"/" + RegexConstants.GetRegularExpressionForJson(RegexConstants.CreditCard) + "/\", \"ng-pattern-msg\": \"" + ErrorMessages.CreditCard + "\", \"ng-maxlength\": 30, \"ng-maxlength-msg\": \"" + ErrorMessages.VisaLength + "\", \"ng-minlength\": 12, \"ng-minlength-msg\": \"" + ErrorMessages.VisaLength + "\" }");
            valsCC.Append(", url: { \"ng-pattern\": \"/" + RegexConstants.GetRegularExpressionForJson(RegexConstants.Url) + "/\", \"ng-pattern-msg\": \"" + ErrorMessages.Url + "\" }");
            valsCC.Append(" }");
            valsCC.Append("} }");
            _validationsCC = JObject.Parse(valsCC.ToString());

            _emptyValidations = JObject.Parse("{ validations: { model: { } } }");
        }
        private void DealWithProperties(PropertyInfo[] properties, ref GetValidationsParms parms, ref bool isFirstProp)
        {
            foreach (var prop in properties)
            {
                if (prop.CustomAttributes != null && prop.CustomAttributes.Count() > 0)
                {
                    var attrStr     = new StringBuilder();
                    var isFirstAttr = true;
                    var displayName = GetDisplayName(prop);

                    foreach (var attr in prop.CustomAttributes)
                    {
                        var converter = _converters.FirstOrDefault(vc => vc.IsAttributeMatch(attr));
                        if (converter != null)
                        {
                            converter.Convert(prop.Name, displayName, attr, attrStr, isFirstAttr, parms.ResourceNamespace, parms.ResourceAssemblyName);
                            isFirstAttr = false;
                        }
                    }

                    if (!isFirstAttr)
                    {
                        var sep = isFirstProp ? string.Empty : ",";

                        if (parms.UseCamelCaseForProperties)
                        {
                            parms.JsonString.Append(sep + CamelCaseProperty(prop.Name) + ": { ");
                        }
                        else
                        {
                            parms.JsonString.Append(sep + prop.Name + ": { ");
                        }
                        parms.JsonString.Append(attrStr.ToString());
                        parms.JsonString.Append("}");

                        isFirstProp = false;
                    }
                }
            }
        }