Inheritance: System.ComponentModel.DataAnnotations.StringLengthAttribute
Example #1
0
 /// <summary>
 /// 验证将要给的值是否合格
 /// </summary>
 /// <param name="slAttribute"></param>
 /// <param name="paraVal"></param>
 /// <returns></returns>
 private static bool ValidValue(StringLengthAttribute slAttribute, string paraVal)
 {
     if (slAttribute.IsValid(paraVal))
     {
         return(true);
     }
     return(false);
 }
        public void Strind_Length_Less_Than_3()
        {
            var validationService = new StringLengthAttribute(3, "test");
            var actual            = validationService.IsValid("ds");

            Assert.AreEqual(actual.ValidationResult, ValidationResult.Success);
            Assert.AreEqual(actual.ErrorMessage, null);
        }
 public void StringLengthAttribute_Fail_Min_Exceed_Max() {
     StringLengthAttribute attr = new StringLengthAttribute(5);
     attr.MinimumLength = 10;
     ExceptionHelper.ExpectException<InvalidOperationException>(delegate() {
         attr.IsValid("");
     },
     String.Format(CultureInfo.CurrentCulture, Resources.DataAnnotationsResources.RangeAttribute_MinGreaterThanMax, 5, 10));
 }
        public void StringLengthAttribute_Invalid_Ctor_And_MinLength_No_Exceptions()
        {
            StringLengthAttribute attr = new StringLengthAttribute(-10);

            attr.MinimumLength = -5;
            Assert.AreEqual(-5, attr.MinimumLength);
            Assert.AreEqual(-10, attr.MaximumLength);
        }
        public void String_Is_Included_In_The_Interval()
        {
            var validationService = new StringLengthAttribute(3, 7, "test");
            var actual            = validationService.IsValid("dsjhjh");

            Assert.AreEqual(actual.ValidationResult, ValidationResult.Success);
            Assert.AreEqual(actual.ErrorMessage, null);
        }
Example #6
0
 private int GetColumnLength(StringLengthAttribute columnAttribute)
 {
     if (columnAttribute != null && (columnAttribute.MaximumLength > 0))
     {
         return(columnAttribute.MaximumLength);
     }
     return(255);
 }
        public void StringLengthAttribute_Ctor_And_MinLength()
        {
            StringLengthAttribute attr = new StringLengthAttribute(10);

            attr.MinimumLength = 5;
            Assert.AreEqual(10, attr.MaximumLength);
            Assert.AreEqual(5, attr.MinimumLength);
        }
        public void String_Is_Not_Included_In_The_Interval()
        {
            var validationService = new StringLengthAttribute(3, 7, "test");
            var actual            = validationService.IsValid("dsjhdlfgfdkjjdfjh");

            Assert.AreEqual(actual.ValidationResult, ValidationResult.StringLengthError);
            Assert.AreEqual(actual.ErrorMessage, "The length of the test property is not included between 3 and 7");
        }
        public void Strind_Length_More_Than_3()
        {
            var validationService = new StringLengthAttribute(3, "test");
            var actual            = validationService.IsValid("dsjhjh");

            Assert.AreEqual(actual.ValidationResult, ValidationResult.StringLengthError);
            Assert.AreEqual(actual.ErrorMessage, "The length of the test property is more than 3");
        }
        public void StringLengthAttribute_Fail_Negative_Max()
        {
            StringLengthAttribute attr = new StringLengthAttribute(-10);

            ExceptionHelper.ExpectException <InvalidOperationException>(delegate() {
                attr.IsValid("");
            }, Resources.DataAnnotationsResources.StringLengthAttribute_InvalidMaxLength);
        }
        public void CreateValidationMetadata(ValidationMetadataProviderContext context)
        {
            if (context == null)
            {
                throw new ArgumentNullException(nameof(context));
            }

            var viewConfig = ServiceLocator.GetViewConfigure(context.Key.ContainerType);

            if (viewConfig != null && context.Key.Name.IsNotNullAndWhiteSpace())
            {
                var descriptor = viewConfig.GetViewPortDescriptor(context.Key.Name);
                if (descriptor != null)
                {
                    descriptor.Validator.Each(v =>
                    {
                        v.DisplayName = descriptor.DisplayName;
                        if (v is RangeValidator)
                        {
                            RangeValidator valid = (RangeValidator)v;
                            RangeAttribute range = new RangeAttribute(valid.Min, valid.Max);
                            range.ErrorMessage   = valid.ErrorMessage;

                            context.ValidationMetadata.ValidatorMetadata.Add(range);
                        }
                        else if (v is RegularValidator)
                        {
                            RegularValidator valid             = (RegularValidator)v;
                            RegularExpressionAttribute regular = new RegularExpressionAttribute(valid.Expression);
                            regular.ErrorMessage = valid.ErrorMessage;
                            context.ValidationMetadata.ValidatorMetadata.Add(regular);
                        }
                        else if (v is RemoteValidator)
                        {
                            RemoteValidator valid  = (RemoteValidator)v;
                            RemoteAttribute remote = new RemoteAttribute(valid.Action, valid.Controller, valid.Area);
                            remote.ErrorMessage    = valid.ErrorMessage;
                            context.ValidationMetadata.ValidatorMetadata.Add(remote);
                        }
                        else if (v is RequiredValidator)
                        {
                            RequiredValidator valid    = (RequiredValidator)v;
                            RequiredAttribute required = new RequiredAttribute();
                            required.ErrorMessage      = valid.ErrorMessage;
                            context.ValidationMetadata.ValidatorMetadata.Add(required);
                        }
                        else if (v is StringLengthValidator)
                        {
                            StringLengthValidator valid        = (StringLengthValidator)v;
                            StringLengthAttribute stringLength = new StringLengthAttribute(valid.Max);
                            stringLength.ErrorMessage          = valid.ErrorMessage;
                            context.ValidationMetadata.ValidatorMetadata.Add(stringLength);
                        }
                    });
                }
            }
        }
Example #12
0
 /// <summary>
 /// 初始化字符串长度验证
 /// </summary>
 private void InitStringLength(StringLengthAttribute attribute)
 {
     if (attribute.MinimumLength <= 0)
     {
         _control.MaxLength(attribute.MaximumLength);
         return;
     }
     _control.Length(attribute.MinimumLength, attribute.MaximumLength);
 }
        public void FormatErrorMessage_MinimumLength_CustomError()
        {
            var attrib = new StringLengthAttribute(3)
            {
                MinimumLength = 1, ErrorMessage = "Foo {0} Bar {1} Baz {2}"
            };

            Assert.AreEqual("Foo SOME_NAME Bar 3 Baz 1", attrib.FormatErrorMessage("SOME_NAME"));
        }
Example #14
0
        public SaveResult SaveBodyContent(UpdatePropertyData updatePropertyData)
        {
            HashSet <Type> types      = TypeHelper.GetAllConcreteTypesAssignableFrom <SystemEntity>();
            Type           entityType = types.FirstOrDefault(t => t.Name == updatePropertyData.Type);

            if (entityType == null)
            {
                return(new SaveResult(false, string.Format(_stringResourceProvider.GetValue("Admin Inline Editing Save Entity Not Found", "Could not find entity type '{0}'"), updatePropertyData.Type)));
            }
            object entity = _session.Get(entityType, updatePropertyData.Id);

            if (entity == null)
            {
                return(new SaveResult(false,
                                      string.Format(_stringResourceProvider.GetValue("Admin InlineEditing Save Not Found", "Could not find entity of type '{0}' with id {1}"), updatePropertyData.Type,
                                                    updatePropertyData.Id)));
            }
            PropertyInfo propertyInfo =
                entityType.GetProperties().FirstOrDefault(info => info.Name == updatePropertyData.Property);

            if (propertyInfo == null)
            {
                return(new SaveResult(false,
                                      string.Format(_stringResourceProvider.GetValue("Admin InlineEditing Save NotFound", "Could not find entity of type '{0}' with id {1}"), updatePropertyData.Type,
                                                    updatePropertyData.Id)));
            }
            StringLengthAttribute stringLengthAttribute = propertyInfo.GetCustomAttributes(true).FirstOrDefault(x => x.GetType() == typeof(StringLengthAttribute)) as StringLengthAttribute;

            if (stringLengthAttribute != null && updatePropertyData.Content.Length > stringLengthAttribute.MaximumLength)
            {
                return(new SaveResult
                {
                    success = false,
                    message = string.Format(_stringResourceProvider.GetValue("Admin InlineEditing Save MaxLength", "Could not save property. The maximum length for this field is {0} characters."), stringLengthAttribute.MaximumLength)
                });
            }
            if (string.IsNullOrWhiteSpace(updatePropertyData.Content) &&
                propertyInfo.GetCustomAttributes(typeof(RequiredAttribute), false).Any())
            {
                return(new SaveResult(false,
                                      string.Format(_stringResourceProvider.GetValue("Admin InlineEditing Save Required", "Could not edit '{0}' as it is required"), updatePropertyData.Property)));
            }

            try
            {
                propertyInfo.SetValue(entity, updatePropertyData.Content, null);
                _session.Transact(session => session.SaveOrUpdate(entity));
            }
            catch (Exception ex)
            {
                CurrentRequestData.ErrorSignal.Raise(ex);

                return(new SaveResult(false, string.Format(_stringResourceProvider.GetValue("Admin InlineEditing Save Error", "Could not save to database '{0}' due to unknown error. Please check log."), updatePropertyData.Property)));
            }

            return(new SaveResult());
        }
Example #15
0
        /// <summary>
        /// Called by the framework when the component needs to be rendered as HTML.
        /// </summary>
        /// <param name="model">The model being rendered by the component.</param>
        /// <returns>The component rendered as HTML.</returns>
        public Task <string> RenderAsync(object model)
        {
            string text;

            if (model is MultiString)
            {
                text = (MultiString)model;
            }
            else
            {
                text = (string)model;
            }

            int emHeight = PropData.GetAdditionalAttributeValue("EmHeight", 10);

            HtmlBuilder hb = new HtmlBuilder();

            YTagBuilder tag = new YTagBuilder("textarea");

            tag.AddCssClass("yt_textareasourceonly");
            tag.AddCssClass("t_edit");
            tag.AddCssClass("k-textbox"); // USE KENDO style
            FieldSetup(tag, Validation ? FieldType.Validated : FieldType.Normal);
            tag.Attributes.Add("id", ControlId);
            tag.Attributes.Add("rows", emHeight.ToString());

            // handle StringLengthAttribute as maxlength
            StringLengthAttribute lenAttr = PropData.TryGetAttribute <StringLengthAttribute>();

            if (lenAttr != null)
            {
#if DEBUG
                if (tag.Attributes.ContainsKey("maxlength"))
                {
                    throw new InternalError($"Both StringLengthAttribute and maxlength specified - {FieldName}");
                }
#endif
                int maxLength = lenAttr.MaximumLength;
                if (maxLength > 0 && maxLength <= 8000)
                {
                    tag.MergeAttribute("maxlength", maxLength.ToString());
                }
            }
#if DEBUG
            if (lenAttr == null && !tag.Attributes.ContainsKey("maxlength"))
            {
                throw new InternalError($"No max string length given using StringLengthAttribute or maxlength - {FieldName}");
            }
#endif

            tag.SetInnerText(text);
            hb.Append(tag.ToString(YTagRenderMode.Normal));

            Manager.ScriptManager.AddLast($@"new YetaWF_ComponentsHTML.TextAreaSourceOnlyEditComponent('{ControlId}');");

            return(Task.FromResult(hb.ToString()));
        }
Example #16
0
        void InstantiateColumn(ref int currentPos, string StoragePath, string TableName, MemberInfo member, Type type, out int pos)
        {
            KeyAttribute          key          = (KeyAttribute)member.GetCustomAttribute(typeof(KeyAttribute));
            StringLengthAttribute stringLength = (StringLengthAttribute)member.GetCustomAttribute(typeof(StringLengthAttribute));
            MaxLengthAttribute    maxLength    = (MaxLengthAttribute)member.GetCustomAttribute(typeof(MaxLengthAttribute));

            pos = key == null ? ++currentPos : 0;
            Common.GenericCallHelper <TableStorage <T> >("InstantiateColumnGeneric", type, this, pos, StoragePath, TableName, member.Name, stringLength, maxLength);
        }
        public static void Validate_MinimumLengthGreaterThanMaximumLength_ThrowsInvalidOperationException()
        {
            var attribute = new StringLengthAttribute(42)
            {
                MinimumLength = 43
            };

            Assert.Throws <InvalidOperationException>(() => attribute.Validate("Any", new ValidationContext(new object())));
        }
        public void FormatErrorMessage_MinimumLength()
        {
            var attrib = new StringLengthAttribute(3)
            {
                MinimumLength = 1
            };

            Assert.AreEqual(String.Format(CultureInfo.CurrentCulture, Resources.DataAnnotationsResources.StringLengthAttribute_ValidationErrorIncludingMinimum, "SOME_NAME", 3, 1), attrib.FormatErrorMessage("SOME_NAME"));
        }
Example #19
0
        public StringLengthHandlerTest()
        {
            Sut = new StringLenghtHandler();

            StringLengthAttributeWithMaxValue        = new StringLengthAttribute(TEST_MAX);;
            StringLengthAttributeWithMinAndMaxValues = new StringLengthAttribute(TEST_MAX)
            {
                MinimumLength = TEST_MIN
            };
        }
 /// <summary>
 /// 获取错误消息
 /// </summary>
 private string ErrorMessage(FormField field, StringLengthAttribute attribute)
 {
     if (attribute.MaximumLength == attribute.MinimumLength)
     {
         return(string.Format(new T("Length of {0} must be {1}"),
                              new T(field.Attribute.Name), attribute.MinimumLength));
     }
     return(string.Format(new T("Length of {0} must between {1} and {2}"),
                          new T(field.Attribute.Name), attribute.MinimumLength, attribute.MaximumLength));
 }
 public void StringLengthAttribute_IsValid_Min_And_Max() {
     StringLengthAttribute attr = new StringLengthAttribute(4);
     attr.MinimumLength = 2;
     Assert.IsFalse(attr.IsValid(""));
     Assert.IsFalse(attr.IsValid("a"));
     Assert.IsTrue(attr.IsValid("ab"));
     Assert.IsTrue(attr.IsValid("abc"));
     Assert.IsTrue(attr.IsValid("abcd"));
     Assert.IsFalse(attr.IsValid("abcde"));
 }
        /// <summary>
        /// Creates the validator.
        /// </summary>
        /// <param name="modelMetadata">The model metadata.</param>
        /// <param name="context">The context.</param>
        /// <returns></returns>
        protected override ModelValidator CreateValidatorCore(ExtendedModelMetadata modelMetadata, ControllerContext context)
        {
            var attribute = new StringLengthAttribute(Maximum)
            {
                MinimumLength = Minimum
            };

            PopulateErrorMessage(attribute);
            return(new StringLengthAttributeAdapter(modelMetadata, context, attribute));
        }
        public void StringLengthAttribute_Fail_Min_Exceed_Max()
        {
            StringLengthAttribute attr = new StringLengthAttribute(5);

            attr.MinimumLength = 10;
            ExceptionHelper.ExpectException <InvalidOperationException>(delegate() {
                attr.IsValid("");
            },
                                                                        String.Format(CultureInfo.CurrentCulture, Resources.DataAnnotationsResources.RangeAttribute_MinGreaterThanMax, 5, 10));
        }
        public static MvcHtmlString MakeTextfield <TModel, TProperty>(this HtmlHelper <TModel> helper, MaterialTextfieldType type, Expression <Func <TModel, TProperty> > expression,
                                                                      TProperty value = default(TProperty))
        {
            MemberInfo           memberInfo           = (expression.Body as MemberExpression)?.Member;
            DisplayNameAttribute displayNameAttribute = memberInfo.GetCustomAttribute <DisplayNameAttribute>();
            DataTypeAttribute    dataTypeAttribute    = memberInfo.GetCustomAttribute <DataTypeAttribute>();
            LocalizationProvider localization         = helper.ViewBag.LocalizationProvider as LocalizationProvider;
            string name                    = memberInfo.Name;
            string displayName             = localization[displayNameAttribute?.DisplayName ?? name];
            string inputType               = null;
            bool   isSpellcheckingDisabled = false;

            switch (dataTypeAttribute?.DataType)
            {
            case DataType.EmailAddress:
                inputType = "email";
                isSpellcheckingDisabled = true;
                break;

            case DataType.Password:
                inputType = "password";
                break;

            case DataType.PhoneNumber:
                inputType = "tel";
                isSpellcheckingDisabled = true;
                break;

            case DataType.Url:
            default:
                inputType = "text";
                if (dataTypeAttribute?.DataType == DataType.Url)
                {
                    isSpellcheckingDisabled = true;
                }
                break;
            }
            RequiredAttribute            requiredAttribute     = memberInfo.GetCustomAttribute <RequiredAttribute>();
            StringLengthAttribute        stringLengthAttribute = memberInfo.GetCustomAttribute <StringLengthAttribute>();
            IDictionary <string, object> attributes            = new Dictionary <string, object>();

            if (requiredAttribute != null)
            {
                attributes.Add("required", "required");
            }
            if (stringLengthAttribute != null)
            {
                attributes.Add("maxlength", stringLengthAttribute.MaximumLength);
            }
            if (isSpellcheckingDisabled)
            {
                attributes.Add("spellcheck", false);
            }
            return(MakeTextfield(helper, type, name, displayName, inputType, attributes, value));
        }
Example #25
0
        /// <summary>
        /// Adds a StringLengthAttribute.
        /// </summary>
        /// <param name="max"></param>
        /// <param name="errMsg">Gets or sets an error message to associate with a validation control if validation fails.</param>
        /// <returns></returns>
        public BaValidatorList StringLength(int max, string errMsg = null)
        {
            var att = new StringLengthAttribute(max);

            if (errMsg != null)
            {
                att.ErrorMessage = errMsg;
            }
            Add(att);
            return(this);
        }
Example #26
0
        public void Setup()
        {
            var attribute1 = new StringLengthAttribute(5);

            attribute1.ErrorMessage = "length";
            var attribute2 = new RegularExpressionAttribute("a*");

            attribute2.ErrorMessage = "regex";

            this.validator = new ValidationAttributeValidator(attribute1, attribute2);
        }
Example #27
0
        public void StringLengthAdapter_SetsExceededErrorMessage()
        {
            StringLengthAttribute attribute = new StringLengthAttribute(128);

            new StringLengthAdapter(attribute);

            String expected = Validations.StringLength;
            String actual   = attribute.ErrorMessage;

            Assert.Equal(expected, actual);
        }
Example #28
0
        public void StringLengthAdapter_SetsMaxLengthErrorMessage()
        {
            StringLengthAttribute attribute = new StringLengthAttribute(128);

            new StringLengthAdapter(metadata, new ControllerContext(), attribute);

            String actual   = Validations.FieldMustNotExceedLength;
            String expected = attribute.ErrorMessage;

            Assert.AreEqual(expected, actual);
        }
        private static void ValidateStringLengthAttribute(StringLengthAttribute attribute, PropertyInfo property, T model)
        {
            string value = (property.GetValue(model, null) ?? string.Empty).ToString();

            if (value.Length <= attribute.MaximumLength && value.Length >= attribute.MinimumLength)
            {
                return;
            }
            // TODO: Add descriptive error message default
            throw new ModelValidationException(property.Name, value, attribute.ErrorMessage);
        }
Example #30
0
        /// <summary>
        /// Called by the framework when the component needs to be rendered as HTML.
        /// </summary>
        /// <param name="model">The model being rendered by the component.</param>
        /// <returns>The component rendered as HTML.</returns>
        public async Task <string> RenderAsync(string model)
        {
            HtmlAttributes.Add("class", "yt_text40");
            StringLengthAttribute lenAttr = PropData.TryGetAttribute <StringLengthAttribute>();

            if (lenAttr == null)
            {
                HtmlAttributes.Add("maxlength", Globals.MaxEmail.ToString());
            }
            return(await TextEditComponent.RenderTextAsync(this, model?.ToString() ?? "", "yt_email"));
        }
Example #31
0
        public static int GetMaxLengthFromStringLengthAttribute(Type modelClass, string propertyName)
        {
            int maxLength = 0;
            StringLengthAttribute strLenAttr = modelClass.GetProperty(propertyName).GetCustomAttributes(typeof(StringLengthAttribute), false).Cast <StringLengthAttribute>().SingleOrDefault();

            if (strLenAttr != null)
            {
                maxLength = strLenAttr.MaximumLength;
            }
            return(maxLength);
        }
        public static string GetStringLengthErrorMessage(int?minimumLength, int maximumLength, string field)
        {
            var attr = new StringLengthAttribute(maximumLength);

            if (minimumLength != null)
            {
                attr.MinimumLength = (int)minimumLength;
            }

            return(attr.FormatErrorMessage(field));
        }
 public static void Validate_ValueNotString_ThrowsInvalidCastException()
 {
     var attribute = new StringLengthAttribute(42);
     Assert.Throws<InvalidCastException>(() => attribute.Validate(new object(), new ValidationContext(new object())));
 }
 public static void Validate_MinimumLengthGreaterThanMaximumLength_ThrowsInvalidOperationException()
 {
     var attribute = new StringLengthAttribute(42) { MinimumLength = 43 };
     Assert.Throws<InvalidOperationException>(() => attribute.Validate("Any", new ValidationContext(new object())));
 }
 public static void Validate_NegativeMaximumLength_ThrowsInvalidOperationException()
 {
     var attribute = new StringLengthAttribute(-1);
     Assert.Throws<InvalidOperationException>(() => attribute.Validate("Any", new ValidationContext(new object())));
 }
 public static void MinimumLength_GetSet_RetunsExpected(int newValue)
 {
     var attribute = new StringLengthAttribute(42);
     attribute.MinimumLength = newValue;
     Assert.Equal(newValue, attribute.MinimumLength);
 }
 public static void Ctor_Int(int maximumLength)
 {
     var attribute = new StringLengthAttribute(maximumLength);
     Assert.Equal(maximumLength, attribute.MaximumLength);
     Assert.Equal(0, attribute.MinimumLength);
 }
        internal static ModelDefinition GetModelDefinition(this Type modelType)
        {
            ModelDefinition modelDef;

            if (typeModelDefinitionMap.TryGetValue(modelType, out modelDef))
                return modelDef;

            var modelAliasAttr = modelType.FirstAttribute<AliasAttribute>();
            var schemaAttr = modelType.FirstAttribute<SchemaAttribute>();
            modelDef = new ModelDefinition {
                ModelType = modelType,
                Name = modelType.Name,
                Alias = modelAliasAttr != null ? modelAliasAttr.Name : null,
                Schema = schemaAttr != null ? schemaAttr.Name : null
            };

            modelDef.CompositeIndexes.AddRange(
                modelType.GetCustomAttributes(typeof(CompositeIndexAttribute), true).ToList()
                .ConvertAll(x => (CompositeIndexAttribute)x));

            var objProperties = modelType.GetProperties(
                BindingFlags.Public | BindingFlags.Instance).ToList();

            var hasIdField = CheckForIdField(objProperties);

            var i = 0;
            foreach (var propertyInfo in objProperties)
            {
                var sequenceAttr = propertyInfo.FirstAttribute<SequenceAttribute>();
                var computeAttr= propertyInfo.FirstAttribute<ComputeAttribute>();
                var pkAttribute = propertyInfo.FirstAttribute<PrimaryKeyAttribute>();
                var decimalAttribute = propertyInfo.FirstAttribute<DecimalLengthAttribute>();
                var belongToAttribute = propertyInfo.FirstAttribute<BelongToAttribute>();
                var isFirst = i++ == 0;

                var isPrimaryKey = propertyInfo.Name == OrmLiteConfig.IdField || (!hasIdField && isFirst)
                    || pkAttribute != null;

                var isNullableType = IsNullableType(propertyInfo.PropertyType);

                var isNullable = (!propertyInfo.PropertyType.IsValueType
                                   && propertyInfo.FirstAttribute<RequiredAttribute>() == null)
                                 || isNullableType;

                var propertyType = isNullableType
                    ? Nullable.GetUnderlyingType(propertyInfo.PropertyType)
                    : propertyInfo.PropertyType;

                var aliasAttr = propertyInfo.FirstAttribute<AliasAttribute>();

                var indexAttr = propertyInfo.FirstAttribute<IndexAttribute>();
                var isIndex = indexAttr != null;
                var isUnique = isIndex && indexAttr.Unique;

                var stringLengthAttr = propertyInfo.FirstAttribute<StringLengthAttribute>();

                var defaultValueAttr = propertyInfo.FirstAttribute<DefaultAttribute>();

                var referencesAttr = propertyInfo.FirstAttribute<ReferencesAttribute>();
                var foreignKeyAttr = propertyInfo.FirstAttribute<ForeignKeyAttribute>();

                if (decimalAttribute != null && stringLengthAttr == null)
                    stringLengthAttr = new StringLengthAttribute(decimalAttribute.Precision);

                var fieldDefinition = new FieldDefinition {
                    Name = propertyInfo.Name,
                    Alias = aliasAttr != null ? aliasAttr.Name : null,
                    FieldType = propertyType,
                    PropertyInfo = propertyInfo,
                    IsNullable = isNullable,
                    IsPrimaryKey = isPrimaryKey,
                    AutoIncrement =
                        isPrimaryKey &&
                        propertyInfo.FirstAttribute<AutoIncrementAttribute>() != null,
                    IsIndexed = isIndex,
                    IsUnique = isUnique,
                    FieldLength =
                        stringLengthAttr != null
                            ? stringLengthAttr.MaximumLength
                            : (int?)null,
                    DefaultValue =
                        defaultValueAttr != null ? defaultValueAttr.DefaultValue : null,
                    ForeignKey =
                        foreignKeyAttr == null
                            ? referencesAttr == null
                                  ? null
                                  : new ForeignKeyConstraint(referencesAttr.Type)
                            : new ForeignKeyConstraint(foreignKeyAttr.Type,
                                                       foreignKeyAttr.OnDelete,
                                                       foreignKeyAttr.OnUpdate,
                                                       foreignKeyAttr.ForeignKeyName),
                    GetValueFn = propertyInfo.GetPropertyGetterFn(),
                    SetValueFn = propertyInfo.GetPropertySetterFn(),
                    Sequence = sequenceAttr != null ? sequenceAttr.Name : string.Empty,
                    IsComputed = computeAttr != null,
                    ComputeExpression =
                        computeAttr != null ? computeAttr.Expression : string.Empty,
                    Scale = decimalAttribute != null ? decimalAttribute.Scale : (int?)null,
                    BelongToModelName = belongToAttribute != null ? belongToAttribute.BelongToTableType.GetModelDefinition().ModelName : null, 
                };

                if (propertyInfo.FirstAttribute<IgnoreAttribute>() != null)
                  modelDef.IgnoredFieldDefinitions.Add(fieldDefinition);
                else
                  modelDef.FieldDefinitions.Add(fieldDefinition);                
            }

            modelDef.SqlSelectAllFromTable = "SELECT {0} FROM {1} ".Fmt(OrmLiteConfig.DialectProvider.GetColumnNames(modelDef),
                                                                        OrmLiteConfig.DialectProvider.GetQuotedTableName(
                                                                            modelDef));
            Dictionary<Type, ModelDefinition> snapshot, newCache;
            do
            {
                snapshot = typeModelDefinitionMap;
                newCache = new Dictionary<Type, ModelDefinition>(typeModelDefinitionMap);
                newCache[modelType] = modelDef;

            } while (!ReferenceEquals(
                Interlocked.CompareExchange(ref typeModelDefinitionMap, newCache, snapshot), snapshot));

            return modelDef;
        }
        internal static ModelDefinition GetModelDefinition(this Type modelType)
        {
            ModelDefinition modelDef;
                        
            if (typeModelDefinitionMap.TryGetValue(modelType, out modelDef))
                return modelDef;

            var modelAliasAttr = modelType.FirstAttribute<AliasAttribute>();

            var fromAttr= modelType.FirstAttribute<SelectFromAttribute>();
            string tableAlias; //=null;
            string modelName=null;
            Type fromType=null;
            StringBuilder join = new StringBuilder();
            
            if (fromAttr!=null){
                tableAlias= fromAttr.Alias;
                fromType=  fromAttr.From;
                modelName= fromType.GetModelDefinition().ModelName;
            }
            else if (modelType.BaseType!=typeof(Object)){
                fromType= modelType.BaseType;
                modelName=fromType.GetModelDefinition().ModelName;
                tableAlias= modelName;
            }
            else
                tableAlias=modelAliasAttr != null ? modelAliasAttr.Name : modelType.Name;
            
            //if(fromType!=null){
                
                var joinAttrList = modelType.GetCustomAttributes(typeof(JoinToAttribute), true).ToList()
                    .ConvertAll(x => (JoinToAttribute)x).OrderBy(x=>x.Order).ToList();
                
                foreach(var ja in joinAttrList){
                    string parentField;
                    string childField;

                    FieldDefinition fd;
                    if(ja.Parent==null && fromType==null)
                        fd=null;
                    else 
                        fd= ((ja.Parent!=null)? ja.Parent:fromType).
                        GetModelDefinition().FieldDefinitions.FirstOrDefault(x=>x.Name==ja.ParentProperty);

                    if(fd!=default(FieldDefinition) ) 
                        parentField= fd.FieldName;
                    else
                    {
                        parentField= modelType.GetFieldName(ja.ParentProperty);
                    }
                    
                    fd= ja.Child.GetModelDefinition().FieldDefinitions.FirstOrDefault(x=>x.Name==ja.ChildProperty);
                    if(fd!=default(FieldDefinition) ) 
                        childField= fd.FieldName;
                    else
                        childField= ja.ChildProperty;
                    
                    join.AppendFormat("\n{0} Join {1} {2} on {3}={4}",ja.JoinType,
                        OrmLiteConfig.DialectProvider.GetQuotedName( ja.Child.GetModelDefinition().ModelName),
                        OrmLiteConfig.DialectProvider.GetQuotedName(ja.ChildAlias), 
                        (ja.ParentAlias.IsNullOrEmpty() && tableAlias.IsNullOrEmpty())?
                                  string.Format("{0}",OrmLiteConfig.DialectProvider.GetQuotedName(parentField))
                                  :string.Format("{0}.{1}",
                            OrmLiteConfig.DialectProvider.GetQuotedName(ja.ParentAlias??tableAlias),
                            OrmLiteConfig.DialectProvider.GetQuotedName(parentField)),


                        string.Format("{0}.{1}",
                            OrmLiteConfig.DialectProvider.GetQuotedName(ja.ChildAlias),
                            OrmLiteConfig.DialectProvider.GetQuotedName(childField))
                        );
                }
            //}
            

            var schemaAttr = modelType.FirstAttribute<SchemaAttribute>();
            modelDef = new ModelDefinition
            {
                ModelType = modelType,
                Name = modelName?? modelType.Name,
                Alias = modelAliasAttr != null ? modelAliasAttr.Name : null,
                Schema = schemaAttr != null ? schemaAttr.Name : null,
                TableAlias= tableAlias,
                Join = join.Length==0? null: join.ToString()
            };

            modelDef.CompositeIndexes.AddRange(
                modelType.GetCustomAttributes(typeof(CompositeIndexAttribute), true).ToList()
                .ConvertAll(x => (CompositeIndexAttribute)x));

            var objProperties = modelType.GetProperties(
                BindingFlags.Public | BindingFlags.Instance).ToList();

            var hasIdField = CheckForIdField(objProperties);

            var i = 0;
            foreach (var propertyInfo in objProperties)
            {
                if (propertyInfo.FirstAttribute<IgnoreAttribute>()!=null) continue;
                var sequenceAttr = propertyInfo.FirstAttribute<SequenceAttribute>();
                var computeAttr= propertyInfo.FirstAttribute<ComputeAttribute>();
                var pkAttribute = propertyInfo.FirstAttribute<PrimaryKeyAttribute>();
                var decimalAttribute = propertyInfo.FirstAttribute<DecimalLengthAttribute>();
                var isFirst = i++ == 0;

                var isPrimaryKey = propertyInfo.Name ==OrmLiteConfig.IdField || (!hasIdField && isFirst)
                    || pkAttribute != null;

                var isNullableType = IsNullableType(propertyInfo.PropertyType);

                var isNullable = (!propertyInfo.PropertyType.IsValueType
                                   && propertyInfo.FirstAttribute<RequiredAttribute>() == null)
                                 || isNullableType;

                var propertyType = isNullableType
                    ? Nullable.GetUnderlyingType(propertyInfo.PropertyType)
                    : propertyInfo.PropertyType;

                var aliasAttr = propertyInfo.FirstAttribute<AliasAttribute>();

                var indexAttr = propertyInfo.FirstAttribute<IndexAttribute>();
                var isIndex = indexAttr != null;
                var isUnique = isIndex && indexAttr.Unique;

                var stringLengthAttr = propertyInfo.FirstAttribute<StringLengthAttribute>();

                var defaultValueAttr = propertyInfo.FirstAttribute<DefaultAttribute>();

                var referencesAttr = propertyInfo.FirstAttribute<ReferencesAttribute>();
                
                if(decimalAttribute != null  && stringLengthAttr==null)
                    stringLengthAttr= new StringLengthAttribute(decimalAttribute.Precision);
                
                var belongsToAttr= propertyInfo.FirstAttribute<BelongsToAttribute>();
                
                string fieldAlias=null;
                string belongsToAlias=null;
                string alias=null;
                
                if (belongsToAttr!=null){
                    belongsToAlias= belongsToAttr.ParentAlias;
                    fieldAlias = propertyInfo.Name;
                    var fd= belongsToAttr.Parent.GetModelDefinition().FieldDefinitions.
                        FirstOrDefault(x=>x.Name==(belongsToAttr.PropertyName?? propertyInfo.Name));
                    if(fd!=default(FieldDefinition) ) 
                        alias= fd.FieldName;
                    else alias= propertyInfo.Name ;
                }
                else if(fromType != null && fromType != modelType){
                    var fd= fromType.GetModelDefinition().FieldDefinitions.FirstOrDefault(x=>x.Name==propertyInfo.Name);
                    if(fd!=default(FieldDefinition) ){
                        alias= fd.FieldName;
                        fieldAlias = propertyInfo.Name;
                        belongsToAlias= tableAlias;
                    }
                }
                
                var fieldDefinition = new FieldDefinition
                {
                    Name = propertyInfo.Name,
                    Alias = alias?? (aliasAttr != null ? aliasAttr.Name : null),
                    FieldAlias= fieldAlias,
                    BelongsToAlias= belongsToAlias,
                    FieldType = propertyType,
                    PropertyInfo = propertyInfo,
                    IsNullable = isNullable,
                    IsPrimaryKey = isPrimaryKey,
                    AutoIncrement = isPrimaryKey && propertyInfo.FirstAttribute<AutoIncrementAttribute>() != null,
                    IsIndexed = isIndex,
                    IsUnique = isUnique,
                    FieldLength = stringLengthAttr != null ? stringLengthAttr.MaximumLength : (int?)null,
                    DefaultValue = defaultValueAttr != null ? defaultValueAttr.DefaultValue : null,
                    ReferencesType = referencesAttr != null ? referencesAttr.Type : null,
                    GetValueFn = propertyInfo.GetPropertyGetterFn(),
                    SetValueFn = propertyInfo.GetPropertySetterFn(),
                    Sequence= sequenceAttr!=null?sequenceAttr.Name:string.Empty,
                    IsComputed= computeAttr!=null,
                    ComputeExpression=  computeAttr!=null? computeAttr.Expression: string.Empty,
                    Scale = decimalAttribute != null ? decimalAttribute.Scale : (int?)null,
                };

                modelDef.FieldDefinitions.Add(fieldDefinition);
            }
            modelDef.SqlSelectAllFromTable = "SELECT {0} FROM {1}{2}".Fmt(OrmLiteConfig.DialectProvider.GetColumnNames(modelDef),
                OrmLiteConfig.DialectProvider.GetQuotedTableName(modelDef),
                tableAlias.IsNullOrEmpty()?
                    "":
                    OrmLiteConfig.DialectProvider.GetQuotedName(tableAlias));

            Dictionary<Type, ModelDefinition> snapshot, newCache;
            do
            {
                snapshot = typeModelDefinitionMap;
                newCache = new Dictionary<Type, ModelDefinition>(typeModelDefinitionMap);
                newCache[modelType] = modelDef;

            } while (!ReferenceEquals(
                Interlocked.CompareExchange(ref typeModelDefinitionMap, newCache, snapshot), snapshot));

            return modelDef;
        }
 public void StringLengthAttribute_Invalid_Ctor_And_MinLength_No_Exceptions() {
     StringLengthAttribute attr = new StringLengthAttribute(-10);
     attr.MinimumLength = -5;
     Assert.AreEqual(-5, attr.MinimumLength);
     Assert.AreEqual(-10, attr.MaximumLength);
 }
 public void StringLengthAttribute_Fail_Negative_Max() {
     StringLengthAttribute attr = new StringLengthAttribute(-10);
     ExceptionHelper.ExpectException<InvalidOperationException>(delegate() {
         attr.IsValid("");
     }, Resources.DataAnnotationsResources.StringLengthAttribute_InvalidMaxLength);
 }
 public void StringLengthAttribute_Ctor_And_MinLength() {
     StringLengthAttribute attr = new StringLengthAttribute(10);
     attr.MinimumLength = 5;
     Assert.AreEqual(10, attr.MaximumLength);
     Assert.AreEqual(5, attr.MinimumLength);
 }
 public void StringLengthAttribute_Ctor() {
     StringLengthAttribute attr = new StringLengthAttribute(10);
     Assert.AreEqual(10, attr.MaximumLength);
     Assert.AreEqual(0, attr.MinimumLength);
 }
 public void FormatErrorMessage_MinimumLength_CustomError() {
     var attrib = new StringLengthAttribute(3) { MinimumLength = 1, ErrorMessage = "Foo {0} Bar {1} Baz {2}" };
     Assert.AreEqual("Foo SOME_NAME Bar 3 Baz 1", attrib.FormatErrorMessage("SOME_NAME"));
 }
 public void FormatErrorMessage_MinimumLength() {
     var attrib = new StringLengthAttribute(3) { MinimumLength = 1 };
     Assert.AreEqual(String.Format(CultureInfo.CurrentCulture, Resources.DataAnnotationsResources.StringLengthAttribute_ValidationErrorIncludingMinimum, "SOME_NAME", 3, 1), attrib.FormatErrorMessage("SOME_NAME"));
 }
 public void FormatErrorMessage() {
     var attrib = new StringLengthAttribute(3);
     Assert.AreEqual(String.Format(CultureInfo.CurrentCulture, Resources.DataAnnotationsResources.StringLengthAttribute_ValidationError, "SOME_NAME", 3), attrib.FormatErrorMessage("SOME_NAME"));
 }