MetaColumn.cs source code in C# .NET

Source code for the .NET framework in C#

                        

Code:

/ 4.0 / 4.0 / DEVDIV_TFS / Dev10 / Releases / RTMRel / ndp / fx / src / xsp / System / DynamicData / DynamicData / MetaColumn.cs / 1305376 / MetaColumn.cs

                            using System.ComponentModel; 
using System.ComponentModel.DataAnnotations;
using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
using System.Globalization; 
using System.Linq;
using System.Reflection; 
using System.Security.Permissions; 
using System.Web.DynamicData.ModelProviders;
using System.Web.DynamicData.Util; 

namespace System.Web.DynamicData {
    /// 
    /// Object that represents a database column used by dynamic data 
    /// 
    public class MetaColumn : IFieldFormattingOptions, IMetaColumn { 
        private TypeCode _typeCode = TypeCode.Empty; 
        private Type _type;
        private object _metadataCacheLock = new object(); 

        // text, ntext, varchar(max), nvarchar(max) all have different maximum lengths so this is a minimum value
        // that ensures that all of the abovementioned columns get treated as long strings.
        private static readonly int s_longStringLengthCutoff = ((Int32.MaxValue >> 1) - 4); 

        // Metadata related members 
        private IMetaColumnMetadata _metadata; 
        private bool? _scaffoldValueManual;
        private bool? _scaffoldValueDefault; 

        public MetaColumn(MetaTable table, ColumnProvider columnProvider) {
            Table = table;
            Provider = columnProvider; 
        }
 
        ///  
        /// The collection of metadata attributes that apply to this column
        ///  
        public AttributeCollection Attributes {
            get {
                return Metadata.Attributes;
            } 
        }
 
        ///  
        /// The CLR type of the property/column
        ///  
        public Type ColumnType {
            get {
                if (_type == null) {
                    // If it's an Nullable, work with T instead 
                    _type = Misc.RemoveNullableFromType(Provider.ColumnType);
                } 
 
                return _type;
            } 
        }

        /// 
        ///  The DataTypeAttribute used for the column 
        /// 
        public DataTypeAttribute DataTypeAttribute { 
            get { 
                return Metadata.DataTypeAttribute;
            } 
        }

        /// 
        /// This column's defalut value. It is typically used to populate the field when creating a new entry. 
        /// 
        public object DefaultValue { 
            get { 
                return Metadata.DefaultValue;
            } 
        }

        /// 
        /// A description for this column 
        /// 
        public virtual string Description { 
            get { 
                //
                return Metadata.Description; 
            }
        }

        ///  
        /// A friendly display name for this column
        ///  
        public virtual string DisplayName { 
            get {
                // Default to the Name if there is no DisplayName 
                return Metadata.DisplayName ?? Name;
            }
        }
 
        /// 
        /// The PropertyInfo of the property that represents this column on the entity type 
        ///  
        public PropertyInfo EntityTypeProperty { get { return Provider.EntityTypeProperty; } }
 
        /// 
        /// The FilterUIHint used for the column
        /// 
        public string FilterUIHint { 
            get {
                return Metadata.FilterUIHint; 
            } 
        }
 
        /// 
        /// Does this column contain binary data
        /// 
        public bool IsBinaryData { 
            get {
                return ColumnType == typeof(byte[]); 
            } 
        }
 
        /// 
        /// meant to indicate that a member is an extra property that was declared in a partial class
        /// 
        public bool IsCustomProperty { get { return Provider.IsCustomProperty; } } 

        ///  
        /// Is this column a floating point type (float, double, decimal) 
        /// 
        public bool IsFloatingPoint { 
            get {
                return ColumnType == typeof(float) || ColumnType == typeof(double) || ColumnType == typeof(decimal);
            }
        } 

        ///  
        /// This is set for columns that are part of a foreign key. Note that it is NOT set for 
        /// the strongly typed entity ref columns (though those columns 'use' one or more columns
        /// where IsForeignKeyComponent is set). 
        /// 
        public bool IsForeignKeyComponent {
            get { return Provider.IsForeignKeyComponent; }
        } 

        ///  
        /// Is this column's value auto-generated in the database 
        /// 
        public bool IsGenerated { get { return Provider.IsGenerated; } } 

        /// 
        /// Is this column a integer
        ///  
        public bool IsInteger {
            get { 
                return ColumnType == typeof(byte) || ColumnType == typeof(short) || ColumnType == typeof(int) || ColumnType == typeof(long); 
            }
        } 

        /// 
        /// Is this column a 'long' string. This is used to determine whether a textbox or textarea should be used.
        ///  
        public bool IsLongString {
            get { 
                return IsString && Provider.MaxLength >= s_longStringLengthCutoff; 
            }
        } 

        /// 
        /// Is this column part if the table's primary key
        ///  
        public bool IsPrimaryKey { get { return Provider.IsPrimaryKey; } }
 
        ///  
        /// Is this a readonly column
        ///  
        [SuppressMessage("Microsoft.Security", "CA2119:SealMethodsThatSatisfyPrivateInterfaces",
            Justification = "Interface denotes existence of property, not used for security.")]
        public virtual bool IsReadOnly {
            get { 
                return Provider.IsReadOnly || Metadata.IsReadOnly ||
                    (Metadata.EditableAttribute != null && !Metadata.EditableAttribute.AllowEdit); 
            } 
        }
 
        /// 
        /// Specifies if a read-only column (see IsReadOnly) allows for a value to be set on insert.
        /// The default value is false when the column is read-only; true when the column is not read-only.
        /// The default value can be override by using EditableAttribute (note that this will indicate that 
        /// the column is meant to be read only).
        ///  
        public bool AllowInitialValue { 
            get {
                if (IsGenerated) { 
                    // always return false for generated columns, since that is a stronger statement.
                    return false;
                }
 
                return Metadata.EditableAttribute.GetPropertyValue(a => a.AllowInitialValue, !IsReadOnly);
            } 
        } 

        ///  
        /// Does this column require a value
        /// 
        public bool IsRequired {
            get { 
                return Metadata.RequiredAttribute != null;
            } 
        } 

        ///  
        /// Is this column a string
        /// 
        public bool IsString {
            get { 
                return ColumnType == typeof(string);
            } 
        } 

        ///  
        /// The maximun length allowed for this column (applies to string columns)
        /// 
        public int MaxLength {
            get { 
                var stringLengthAttribute = Metadata.StringLengthAttribute;
                return stringLengthAttribute != null ? stringLengthAttribute.MaximumLength : Provider.MaxLength; 
            } 
        }
 
        /// 
        /// The MetaModel that this column belongs to
        /// 
        public MetaModel Model { get { return Table.Model; } } 

        ///  
        /// The column's name 
        /// 
        public string Name { get { return Provider.Name; } } 

        /// 
        /// A value that can be used as a watermark in UI bound to value represented by this column.
        ///  
        public virtual string Prompt { get { return Metadata.Prompt; } }
 
        ///  
        /// the abstraction provider object that was used to construct this metacolumn.
        ///  
        public ColumnProvider Provider { get; private set; }

        /// 
        /// The error message used if this column is required and it is set to empty 
        /// 
        public string RequiredErrorMessage { 
            get { 
                var requiredAttribute = Metadata.RequiredAttribute;
                return requiredAttribute != null ? requiredAttribute.FormatErrorMessage(DisplayName) : String.Empty; 
            }
        }

        ///  
        /// Is it a column that should be displayed (e.g. in a GridView's auto generate mode)
        ///  
        [SuppressMessage("Microsoft.Security", "CA2119:SealMethodsThatSatisfyPrivateInterfaces", 
            Justification = "Interface denotes existence of property, not used for security.")]
        public virtual bool Scaffold { 
            get {
                // If the value was explicitely set, that always takes precedence
                if (_scaffoldValueManual != null) {
                    return _scaffoldValueManual.Value; 
                }
 
                // If there is a DisplayAttribute with an explicit value, always honor it 
                var displayAttribute = Metadata.DisplayAttribute;
                if (displayAttribute != null && displayAttribute.GetAutoGenerateField().HasValue) { 
                    return displayAttribute.GetAutoGenerateField().Value;
                }

                // If there is an explicit Scaffold attribute, always honor it 
                var scaffoldAttribute = Metadata.ScaffoldColumnAttribute;
                if (scaffoldAttribute != null) { 
                    return scaffoldAttribute.Scaffold; 
                }
 
                if (_scaffoldValueDefault == null) {
                    _scaffoldValueDefault = ScaffoldNoCache;
                }
 
                return _scaffoldValueDefault.Value;
            } 
            set { 
                _scaffoldValueManual = value;
            } 
        }

        /// 
        /// Look at various pieces of data on the column to determine whether it's 
        /// Scaffold mode should be on.  This only gets called once per column and the result
        /// is cached 
        ///  
        internal virtual bool ScaffoldNoCache {
            get { 
                // Any field with a UIHint should be included
                if (!String.IsNullOrEmpty(UIHint)) return true;

                // Skip columns that are part of a foreign key, since they are already 'covered' in the 
                // strongly typed foreign key column
                if (IsForeignKeyComponent) return false; 
 
                // Skip generated columns, which are not typically interesting
                if (IsGenerated) return false; 

                // Always include non-generated primary keys
                if (IsPrimaryKey) return true;
 
                // Skip custom properties
                if (IsCustomProperty) return false; 
 
                // Include strings and characters
                if (IsString) return true; 
                if (ColumnType == typeof(char)) return true;

                // Include numbers
                if (IsInteger) return true; 
                if (IsFloatingPoint) return true;
 
                // Include date related columns 
                if (ColumnType == typeof(DateTime)) return true;
                if (ColumnType == typeof(TimeSpan)) return true; 
                if (ColumnType == typeof(DateTimeOffset)) return true;


                // Include bools 
                if (ColumnType == typeof(bool)) return true;
 
                // Include enums 
                Type enumType;
                if (this.IsEnumType(out enumType)) return true; 

                return false;
            }
        } 

        ///  
        /// A friendly short display name for this column. Meant to be used in GridView and similar controls where there might be 
        /// limited column header space
        ///  
        public virtual string ShortDisplayName {
            get {
                // Default to the DisplayName if there is no ShortDisplayName
                return Metadata.ShortDisplayName ?? DisplayName; 
            }
        } 
 
        /// 
        /// The expression used to determine the sort order for this column 
        /// 
        public string SortExpression {
            get {
                return SortExpressionInternal; 
            }
        } 
 
        internal virtual string SortExpressionInternal {
            get { 
                return Provider.IsSortable ? Name : string.Empty;
            }
        }
 
        /// 
        /// The MetaTable that this column belongs to 
        ///  
        public MetaTable Table { get; private set; }
 
        /// 
        /// The TypeCode of this column. It is derived from the ColumnType
        /// 
        public TypeCode TypeCode { 
            get {
                if (_typeCode == TypeCode.Empty) { 
                    _typeCode = DataSourceUtil.TypeCodeFromType(ColumnType); 
                }
 
                return _typeCode;
            }
        }
 
        /// 
        ///  The UIHint used for the column 
        ///  
        public virtual string UIHint {
            get { 
                return Metadata.UIHint;
            }
        }
 
        #region IFieldFormattingOptions Members
 
        ///  
        /// Same semantic as the same property on System.Web.UI.WebControls.BoundField
        ///  
        public bool ApplyFormatInEditMode {
            get {
                return Metadata.ApplyFormatInEditMode;
            } 
        }
 
        ///  
        /// Same semantic as the same property on System.Web.UI.WebControls.BoundField
        ///  
        public bool ConvertEmptyStringToNull {
            get {
                return Metadata.ConvertEmptyStringToNull;
            } 
        }
 
        ///  
        /// Same semantic as the same property on System.Web.UI.WebControls.BoundField
        ///  
        public string DataFormatString {
            get {
                return Metadata.DataFormatString;
            } 
        }
 
        ///  
        /// Same semantic as the same property on System.Web.UI.WebControls.BoundField
        ///  
        public bool HtmlEncode {
            get {
                return Metadata.HtmlEncode;
            } 
        }
 
        ///  
        /// Same semantic as the same property on System.Web.UI.WebControls.BoundField
        ///  
        public string NullDisplayText {
            get {
                return Metadata.NullDisplayText;
            } 
        }
 
        #endregion 

        ///  
        /// Build the attribute collection, later made available through the Attributes property
        /// 
        protected virtual AttributeCollection BuildAttributeCollection() {
            return Provider.Attributes; 
        }
 
        ///  
        /// Perform initialization logic for this column
        ///  
        internal protected virtual void Initialize() { }

        /// 
        /// Resets cached column metadata (i.e. information coming from attributes). The metadata cache will be rebuilt 
        /// the next time any metadata-derived information gets requested.
        ///  
        public void ResetMetadata() { 
            _metadata = null;
        } 

        /// 
        /// Shows the column name. Mostly for debugging purpose.
        ///  
        [SuppressMessage("Microsoft.Security", "CA2123:OverrideLinkDemandsShouldBeIdenticalToBase")]
        public override string ToString() { 
            return GetType().Name + " " + Name; 
        }
 
        internal IMetaColumnMetadata Metadata {
            get {
                // Use a local to avoid returning null if ResetMetadata is called
                IMetaColumnMetadata metadata = _metadata; 
                if (metadata == null) {
                    metadata = new MetaColumnMetadata(this); 
                    _metadata = metadata; 
                }
                return metadata; 
            }
            set {
                // settable for unit testing
                _metadata = value; 
            }
        } 
 
        #region Metadata abstraction
 
        internal interface IMetaColumnMetadata {

            AttributeCollection Attributes { get; }
 
            DisplayAttribute DisplayAttribute { get; }
 
            bool ApplyFormatInEditMode { get; } 

            bool ConvertEmptyStringToNull { get; } 

            bool HtmlEncode { get; }

            string DataFormatString { get; } 

            DataTypeAttribute DataTypeAttribute { get; } 
 
            object DefaultValue { get; }
 
            string Description { get; }

            string DisplayName { get; }
 
            string FilterUIHint { get; }
 
            string ShortDisplayName { get; } 

            string NullDisplayText { get; } 

            string Prompt { get; }

            RequiredAttribute RequiredAttribute { get; } 

            ScaffoldColumnAttribute ScaffoldColumnAttribute { get; } 
 
            StringLengthAttribute StringLengthAttribute { get; }
 
            string UIHint { get; }

            bool IsReadOnly { get; }
 
            EditableAttribute EditableAttribute { get; }
        } 
 
        internal class MetaColumnMetadata : IMetaColumnMetadata {
            private MetaColumn Column { get; set; } 

            public AttributeCollection Attributes { get; private set; }

            public MetaColumnMetadata(MetaColumn column) { 
                Debug.Assert(column != null);
                Column = column; 
 
                Attributes = Column.BuildAttributeCollection();
 
                DisplayAttribute = Attributes.FirstOrDefault();
                DataTypeAttribute = Attributes.FirstOrDefault() ?? GetDefaultDataTypeAttribute();
                DescriptionAttribute = Attributes.FirstOrDefault();
                DefaultValueAttribute = Attributes.FirstOrDefault(); 
                DisplayNameAttribute = Attributes.FirstOrDefault();
                RequiredAttribute = Attributes.FirstOrDefault(); 
                ScaffoldColumnAttribute = Attributes.FirstOrDefault(); 
                StringLengthAttribute = Attributes.FirstOrDefault();
 
                UIHint = GetHint(a => a.PresentationLayer, a => a.UIHint);
                FilterUIHint = GetHint(a => a.PresentationLayer, a => a.FilterUIHint);

                EditableAttribute = Attributes.FirstOrDefault(); 
                IsReadOnly = Attributes.GetAttributePropertyValue(a => a.IsReadOnly, false);
 
                var displayFormatAttribute = Attributes.FirstOrDefault() ?? 
                    (DataTypeAttribute != null ? DataTypeAttribute.DisplayFormat : null);
 
                ApplyFormatInEditMode = displayFormatAttribute.GetPropertyValue(a => a.ApplyFormatInEditMode, false);
                ConvertEmptyStringToNull = displayFormatAttribute.GetPropertyValue(a => a.ConvertEmptyStringToNull, true);
                DataFormatString = displayFormatAttribute.GetPropertyValue(a => a.DataFormatString, String.Empty);
                NullDisplayText = displayFormatAttribute.GetPropertyValue(a => a.NullDisplayText, String.Empty); 
                HtmlEncode = displayFormatAttribute.GetPropertyValue(a => a.HtmlEncode, true);
            } 
 
            public DisplayAttribute DisplayAttribute { get; private set; }
 
            public bool ApplyFormatInEditMode { get; private set; }

            public bool ConvertEmptyStringToNull { get; private set; }
 
            public string DataFormatString { get; private set; }
 
            public DataTypeAttribute DataTypeAttribute { get; private set; } 

            public object DefaultValue { 
                get {
                    return DefaultValueAttribute.GetPropertyValue(a => a.Value, null);
                }
            } 

            private DefaultValueAttribute DefaultValueAttribute { get; set; } 
 
            public string Description {
                get { 
                    return DisplayAttribute.GetPropertyValue(a => a.GetDescription(), null) ??
                        DescriptionAttribute.GetPropertyValue(a => a.Description, null);
                }
            } 

            private DescriptionAttribute DescriptionAttribute { get; set; } 
 
            public string DisplayName {
                get { 
                    return DisplayAttribute.GetPropertyValue(a => a.GetName(), null) ??
                        DisplayNameAttribute.GetPropertyValue(a => a.DisplayName, null);
                }
            } 

            public string ShortDisplayName { 
                get { 
                    return DisplayAttribute.GetPropertyValue(a => a.GetShortName(), null);
                } 
            }

            private DisplayNameAttribute DisplayNameAttribute { get; set; }
 
            public string FilterUIHint { get; private set; }
 
            public EditableAttribute EditableAttribute { get; private set; } 

            public bool IsReadOnly { get; private set; } 

            public string NullDisplayText { get; private set; }

            public string Prompt { 
                get {
                    return DisplayAttribute.GetPropertyValue(a => a.GetPrompt(), null); 
                } 
            }
 
            public RequiredAttribute RequiredAttribute { get; private set; }

            public ScaffoldColumnAttribute ScaffoldColumnAttribute { get; private set; }
 
            public StringLengthAttribute StringLengthAttribute { get; private set; }
 
            public string UIHint { get; private set; } 

            private DataTypeAttribute GetDefaultDataTypeAttribute() { 
                if (Column.IsString) {
                    if (Column.IsLongString) {
                        return new DataTypeAttribute(DataType.MultilineText);
                    } 
                    else {
                        return new DataTypeAttribute(DataType.Text); 
                    } 
                }
 
                return null;
            }

            private string GetHint(Func presentationLayerPropertyAccessor, Func hintPropertyAccessor) where T : Attribute { 
                var uiHints = Attributes.OfType();
                var presentationLayerNotSpecified = uiHints.Where(a => String.IsNullOrEmpty(presentationLayerPropertyAccessor(a))); 
                var presentationLayerSpecified = uiHints.Where(a => !String.IsNullOrEmpty(presentationLayerPropertyAccessor(a))); 

                T uiHintAttribute = presentationLayerSpecified.FirstOrDefault(a => presentationLayerPropertyAccessor(a).ToLower(CultureInfo.InvariantCulture) == "webforms" || 
                                                                                   presentationLayerPropertyAccessor(a).ToLower(CultureInfo.InvariantCulture) == "mvc") ??
                                                  presentationLayerNotSpecified.FirstOrDefault();

                return uiHintAttribute.GetPropertyValue(hintPropertyAccessor); 
            }
 
 
            public bool HtmlEncode {
                get; set; 
            }
        }

        #endregion 

        string IMetaColumn.Description { 
            get { 
                return Description;
            } 
        }

        string IMetaColumn.DisplayName {
            get { 
                return DisplayName;
            } 
        } 

        string IMetaColumn.Prompt { 
            get {
                return Prompt;
            }
        } 

        string IMetaColumn.ShortDisplayName { 
            get { 
                return ShortDisplayName;
            } 
        }

        IMetaTable IMetaColumn.Table {
            get { 
                return Table;
            } 
        } 

        IMetaModel IMetaColumn.Model { 
            get {
                return Model;
            }
        } 
    }
} 

// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
// Copyright (c) Microsoft Corporation. All rights reserved.
using System.ComponentModel; 
using System.ComponentModel.DataAnnotations;
using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
using System.Globalization; 
using System.Linq;
using System.Reflection; 
using System.Security.Permissions; 
using System.Web.DynamicData.ModelProviders;
using System.Web.DynamicData.Util; 

namespace System.Web.DynamicData {
    /// 
    /// Object that represents a database column used by dynamic data 
    /// 
    public class MetaColumn : IFieldFormattingOptions, IMetaColumn { 
        private TypeCode _typeCode = TypeCode.Empty; 
        private Type _type;
        private object _metadataCacheLock = new object(); 

        // text, ntext, varchar(max), nvarchar(max) all have different maximum lengths so this is a minimum value
        // that ensures that all of the abovementioned columns get treated as long strings.
        private static readonly int s_longStringLengthCutoff = ((Int32.MaxValue >> 1) - 4); 

        // Metadata related members 
        private IMetaColumnMetadata _metadata; 
        private bool? _scaffoldValueManual;
        private bool? _scaffoldValueDefault; 

        public MetaColumn(MetaTable table, ColumnProvider columnProvider) {
            Table = table;
            Provider = columnProvider; 
        }
 
        ///  
        /// The collection of metadata attributes that apply to this column
        ///  
        public AttributeCollection Attributes {
            get {
                return Metadata.Attributes;
            } 
        }
 
        ///  
        /// The CLR type of the property/column
        ///  
        public Type ColumnType {
            get {
                if (_type == null) {
                    // If it's an Nullable, work with T instead 
                    _type = Misc.RemoveNullableFromType(Provider.ColumnType);
                } 
 
                return _type;
            } 
        }

        /// 
        ///  The DataTypeAttribute used for the column 
        /// 
        public DataTypeAttribute DataTypeAttribute { 
            get { 
                return Metadata.DataTypeAttribute;
            } 
        }

        /// 
        /// This column's defalut value. It is typically used to populate the field when creating a new entry. 
        /// 
        public object DefaultValue { 
            get { 
                return Metadata.DefaultValue;
            } 
        }

        /// 
        /// A description for this column 
        /// 
        public virtual string Description { 
            get { 
                //
                return Metadata.Description; 
            }
        }

        ///  
        /// A friendly display name for this column
        ///  
        public virtual string DisplayName { 
            get {
                // Default to the Name if there is no DisplayName 
                return Metadata.DisplayName ?? Name;
            }
        }
 
        /// 
        /// The PropertyInfo of the property that represents this column on the entity type 
        ///  
        public PropertyInfo EntityTypeProperty { get { return Provider.EntityTypeProperty; } }
 
        /// 
        /// The FilterUIHint used for the column
        /// 
        public string FilterUIHint { 
            get {
                return Metadata.FilterUIHint; 
            } 
        }
 
        /// 
        /// Does this column contain binary data
        /// 
        public bool IsBinaryData { 
            get {
                return ColumnType == typeof(byte[]); 
            } 
        }
 
        /// 
        /// meant to indicate that a member is an extra property that was declared in a partial class
        /// 
        public bool IsCustomProperty { get { return Provider.IsCustomProperty; } } 

        ///  
        /// Is this column a floating point type (float, double, decimal) 
        /// 
        public bool IsFloatingPoint { 
            get {
                return ColumnType == typeof(float) || ColumnType == typeof(double) || ColumnType == typeof(decimal);
            }
        } 

        ///  
        /// This is set for columns that are part of a foreign key. Note that it is NOT set for 
        /// the strongly typed entity ref columns (though those columns 'use' one or more columns
        /// where IsForeignKeyComponent is set). 
        /// 
        public bool IsForeignKeyComponent {
            get { return Provider.IsForeignKeyComponent; }
        } 

        ///  
        /// Is this column's value auto-generated in the database 
        /// 
        public bool IsGenerated { get { return Provider.IsGenerated; } } 

        /// 
        /// Is this column a integer
        ///  
        public bool IsInteger {
            get { 
                return ColumnType == typeof(byte) || ColumnType == typeof(short) || ColumnType == typeof(int) || ColumnType == typeof(long); 
            }
        } 

        /// 
        /// Is this column a 'long' string. This is used to determine whether a textbox or textarea should be used.
        ///  
        public bool IsLongString {
            get { 
                return IsString && Provider.MaxLength >= s_longStringLengthCutoff; 
            }
        } 

        /// 
        /// Is this column part if the table's primary key
        ///  
        public bool IsPrimaryKey { get { return Provider.IsPrimaryKey; } }
 
        ///  
        /// Is this a readonly column
        ///  
        [SuppressMessage("Microsoft.Security", "CA2119:SealMethodsThatSatisfyPrivateInterfaces",
            Justification = "Interface denotes existence of property, not used for security.")]
        public virtual bool IsReadOnly {
            get { 
                return Provider.IsReadOnly || Metadata.IsReadOnly ||
                    (Metadata.EditableAttribute != null && !Metadata.EditableAttribute.AllowEdit); 
            } 
        }
 
        /// 
        /// Specifies if a read-only column (see IsReadOnly) allows for a value to be set on insert.
        /// The default value is false when the column is read-only; true when the column is not read-only.
        /// The default value can be override by using EditableAttribute (note that this will indicate that 
        /// the column is meant to be read only).
        ///  
        public bool AllowInitialValue { 
            get {
                if (IsGenerated) { 
                    // always return false for generated columns, since that is a stronger statement.
                    return false;
                }
 
                return Metadata.EditableAttribute.GetPropertyValue(a => a.AllowInitialValue, !IsReadOnly);
            } 
        } 

        ///  
        /// Does this column require a value
        /// 
        public bool IsRequired {
            get { 
                return Metadata.RequiredAttribute != null;
            } 
        } 

        ///  
        /// Is this column a string
        /// 
        public bool IsString {
            get { 
                return ColumnType == typeof(string);
            } 
        } 

        ///  
        /// The maximun length allowed for this column (applies to string columns)
        /// 
        public int MaxLength {
            get { 
                var stringLengthAttribute = Metadata.StringLengthAttribute;
                return stringLengthAttribute != null ? stringLengthAttribute.MaximumLength : Provider.MaxLength; 
            } 
        }
 
        /// 
        /// The MetaModel that this column belongs to
        /// 
        public MetaModel Model { get { return Table.Model; } } 

        ///  
        /// The column's name 
        /// 
        public string Name { get { return Provider.Name; } } 

        /// 
        /// A value that can be used as a watermark in UI bound to value represented by this column.
        ///  
        public virtual string Prompt { get { return Metadata.Prompt; } }
 
        ///  
        /// the abstraction provider object that was used to construct this metacolumn.
        ///  
        public ColumnProvider Provider { get; private set; }

        /// 
        /// The error message used if this column is required and it is set to empty 
        /// 
        public string RequiredErrorMessage { 
            get { 
                var requiredAttribute = Metadata.RequiredAttribute;
                return requiredAttribute != null ? requiredAttribute.FormatErrorMessage(DisplayName) : String.Empty; 
            }
        }

        ///  
        /// Is it a column that should be displayed (e.g. in a GridView's auto generate mode)
        ///  
        [SuppressMessage("Microsoft.Security", "CA2119:SealMethodsThatSatisfyPrivateInterfaces", 
            Justification = "Interface denotes existence of property, not used for security.")]
        public virtual bool Scaffold { 
            get {
                // If the value was explicitely set, that always takes precedence
                if (_scaffoldValueManual != null) {
                    return _scaffoldValueManual.Value; 
                }
 
                // If there is a DisplayAttribute with an explicit value, always honor it 
                var displayAttribute = Metadata.DisplayAttribute;
                if (displayAttribute != null && displayAttribute.GetAutoGenerateField().HasValue) { 
                    return displayAttribute.GetAutoGenerateField().Value;
                }

                // If there is an explicit Scaffold attribute, always honor it 
                var scaffoldAttribute = Metadata.ScaffoldColumnAttribute;
                if (scaffoldAttribute != null) { 
                    return scaffoldAttribute.Scaffold; 
                }
 
                if (_scaffoldValueDefault == null) {
                    _scaffoldValueDefault = ScaffoldNoCache;
                }
 
                return _scaffoldValueDefault.Value;
            } 
            set { 
                _scaffoldValueManual = value;
            } 
        }

        /// 
        /// Look at various pieces of data on the column to determine whether it's 
        /// Scaffold mode should be on.  This only gets called once per column and the result
        /// is cached 
        ///  
        internal virtual bool ScaffoldNoCache {
            get { 
                // Any field with a UIHint should be included
                if (!String.IsNullOrEmpty(UIHint)) return true;

                // Skip columns that are part of a foreign key, since they are already 'covered' in the 
                // strongly typed foreign key column
                if (IsForeignKeyComponent) return false; 
 
                // Skip generated columns, which are not typically interesting
                if (IsGenerated) return false; 

                // Always include non-generated primary keys
                if (IsPrimaryKey) return true;
 
                // Skip custom properties
                if (IsCustomProperty) return false; 
 
                // Include strings and characters
                if (IsString) return true; 
                if (ColumnType == typeof(char)) return true;

                // Include numbers
                if (IsInteger) return true; 
                if (IsFloatingPoint) return true;
 
                // Include date related columns 
                if (ColumnType == typeof(DateTime)) return true;
                if (ColumnType == typeof(TimeSpan)) return true; 
                if (ColumnType == typeof(DateTimeOffset)) return true;


                // Include bools 
                if (ColumnType == typeof(bool)) return true;
 
                // Include enums 
                Type enumType;
                if (this.IsEnumType(out enumType)) return true; 

                return false;
            }
        } 

        ///  
        /// A friendly short display name for this column. Meant to be used in GridView and similar controls where there might be 
        /// limited column header space
        ///  
        public virtual string ShortDisplayName {
            get {
                // Default to the DisplayName if there is no ShortDisplayName
                return Metadata.ShortDisplayName ?? DisplayName; 
            }
        } 
 
        /// 
        /// The expression used to determine the sort order for this column 
        /// 
        public string SortExpression {
            get {
                return SortExpressionInternal; 
            }
        } 
 
        internal virtual string SortExpressionInternal {
            get { 
                return Provider.IsSortable ? Name : string.Empty;
            }
        }
 
        /// 
        /// The MetaTable that this column belongs to 
        ///  
        public MetaTable Table { get; private set; }
 
        /// 
        /// The TypeCode of this column. It is derived from the ColumnType
        /// 
        public TypeCode TypeCode { 
            get {
                if (_typeCode == TypeCode.Empty) { 
                    _typeCode = DataSourceUtil.TypeCodeFromType(ColumnType); 
                }
 
                return _typeCode;
            }
        }
 
        /// 
        ///  The UIHint used for the column 
        ///  
        public virtual string UIHint {
            get { 
                return Metadata.UIHint;
            }
        }
 
        #region IFieldFormattingOptions Members
 
        ///  
        /// Same semantic as the same property on System.Web.UI.WebControls.BoundField
        ///  
        public bool ApplyFormatInEditMode {
            get {
                return Metadata.ApplyFormatInEditMode;
            } 
        }
 
        ///  
        /// Same semantic as the same property on System.Web.UI.WebControls.BoundField
        ///  
        public bool ConvertEmptyStringToNull {
            get {
                return Metadata.ConvertEmptyStringToNull;
            } 
        }
 
        ///  
        /// Same semantic as the same property on System.Web.UI.WebControls.BoundField
        ///  
        public string DataFormatString {
            get {
                return Metadata.DataFormatString;
            } 
        }
 
        ///  
        /// Same semantic as the same property on System.Web.UI.WebControls.BoundField
        ///  
        public bool HtmlEncode {
            get {
                return Metadata.HtmlEncode;
            } 
        }
 
        ///  
        /// Same semantic as the same property on System.Web.UI.WebControls.BoundField
        ///  
        public string NullDisplayText {
            get {
                return Metadata.NullDisplayText;
            } 
        }
 
        #endregion 

        ///  
        /// Build the attribute collection, later made available through the Attributes property
        /// 
        protected virtual AttributeCollection BuildAttributeCollection() {
            return Provider.Attributes; 
        }
 
        ///  
        /// Perform initialization logic for this column
        ///  
        internal protected virtual void Initialize() { }

        /// 
        /// Resets cached column metadata (i.e. information coming from attributes). The metadata cache will be rebuilt 
        /// the next time any metadata-derived information gets requested.
        ///  
        public void ResetMetadata() { 
            _metadata = null;
        } 

        /// 
        /// Shows the column name. Mostly for debugging purpose.
        ///  
        [SuppressMessage("Microsoft.Security", "CA2123:OverrideLinkDemandsShouldBeIdenticalToBase")]
        public override string ToString() { 
            return GetType().Name + " " + Name; 
        }
 
        internal IMetaColumnMetadata Metadata {
            get {
                // Use a local to avoid returning null if ResetMetadata is called
                IMetaColumnMetadata metadata = _metadata; 
                if (metadata == null) {
                    metadata = new MetaColumnMetadata(this); 
                    _metadata = metadata; 
                }
                return metadata; 
            }
            set {
                // settable for unit testing
                _metadata = value; 
            }
        } 
 
        #region Metadata abstraction
 
        internal interface IMetaColumnMetadata {

            AttributeCollection Attributes { get; }
 
            DisplayAttribute DisplayAttribute { get; }
 
            bool ApplyFormatInEditMode { get; } 

            bool ConvertEmptyStringToNull { get; } 

            bool HtmlEncode { get; }

            string DataFormatString { get; } 

            DataTypeAttribute DataTypeAttribute { get; } 
 
            object DefaultValue { get; }
 
            string Description { get; }

            string DisplayName { get; }
 
            string FilterUIHint { get; }
 
            string ShortDisplayName { get; } 

            string NullDisplayText { get; } 

            string Prompt { get; }

            RequiredAttribute RequiredAttribute { get; } 

            ScaffoldColumnAttribute ScaffoldColumnAttribute { get; } 
 
            StringLengthAttribute StringLengthAttribute { get; }
 
            string UIHint { get; }

            bool IsReadOnly { get; }
 
            EditableAttribute EditableAttribute { get; }
        } 
 
        internal class MetaColumnMetadata : IMetaColumnMetadata {
            private MetaColumn Column { get; set; } 

            public AttributeCollection Attributes { get; private set; }

            public MetaColumnMetadata(MetaColumn column) { 
                Debug.Assert(column != null);
                Column = column; 
 
                Attributes = Column.BuildAttributeCollection();
 
                DisplayAttribute = Attributes.FirstOrDefault();
                DataTypeAttribute = Attributes.FirstOrDefault() ?? GetDefaultDataTypeAttribute();
                DescriptionAttribute = Attributes.FirstOrDefault();
                DefaultValueAttribute = Attributes.FirstOrDefault(); 
                DisplayNameAttribute = Attributes.FirstOrDefault();
                RequiredAttribute = Attributes.FirstOrDefault(); 
                ScaffoldColumnAttribute = Attributes.FirstOrDefault(); 
                StringLengthAttribute = Attributes.FirstOrDefault();
 
                UIHint = GetHint(a => a.PresentationLayer, a => a.UIHint);
                FilterUIHint = GetHint(a => a.PresentationLayer, a => a.FilterUIHint);

                EditableAttribute = Attributes.FirstOrDefault(); 
                IsReadOnly = Attributes.GetAttributePropertyValue(a => a.IsReadOnly, false);
 
                var displayFormatAttribute = Attributes.FirstOrDefault() ?? 
                    (DataTypeAttribute != null ? DataTypeAttribute.DisplayFormat : null);
 
                ApplyFormatInEditMode = displayFormatAttribute.GetPropertyValue(a => a.ApplyFormatInEditMode, false);
                ConvertEmptyStringToNull = displayFormatAttribute.GetPropertyValue(a => a.ConvertEmptyStringToNull, true);
                DataFormatString = displayFormatAttribute.GetPropertyValue(a => a.DataFormatString, String.Empty);
                NullDisplayText = displayFormatAttribute.GetPropertyValue(a => a.NullDisplayText, String.Empty); 
                HtmlEncode = displayFormatAttribute.GetPropertyValue(a => a.HtmlEncode, true);
            } 
 
            public DisplayAttribute DisplayAttribute { get; private set; }
 
            public bool ApplyFormatInEditMode { get; private set; }

            public bool ConvertEmptyStringToNull { get; private set; }
 
            public string DataFormatString { get; private set; }
 
            public DataTypeAttribute DataTypeAttribute { get; private set; } 

            public object DefaultValue { 
                get {
                    return DefaultValueAttribute.GetPropertyValue(a => a.Value, null);
                }
            } 

            private DefaultValueAttribute DefaultValueAttribute { get; set; } 
 
            public string Description {
                get { 
                    return DisplayAttribute.GetPropertyValue(a => a.GetDescription(), null) ??
                        DescriptionAttribute.GetPropertyValue(a => a.Description, null);
                }
            } 

            private DescriptionAttribute DescriptionAttribute { get; set; } 
 
            public string DisplayName {
                get { 
                    return DisplayAttribute.GetPropertyValue(a => a.GetName(), null) ??
                        DisplayNameAttribute.GetPropertyValue(a => a.DisplayName, null);
                }
            } 

            public string ShortDisplayName { 
                get { 
                    return DisplayAttribute.GetPropertyValue(a => a.GetShortName(), null);
                } 
            }

            private DisplayNameAttribute DisplayNameAttribute { get; set; }
 
            public string FilterUIHint { get; private set; }
 
            public EditableAttribute EditableAttribute { get; private set; } 

            public bool IsReadOnly { get; private set; } 

            public string NullDisplayText { get; private set; }

            public string Prompt { 
                get {
                    return DisplayAttribute.GetPropertyValue(a => a.GetPrompt(), null); 
                } 
            }
 
            public RequiredAttribute RequiredAttribute { get; private set; }

            public ScaffoldColumnAttribute ScaffoldColumnAttribute { get; private set; }
 
            public StringLengthAttribute StringLengthAttribute { get; private set; }
 
            public string UIHint { get; private set; } 

            private DataTypeAttribute GetDefaultDataTypeAttribute() { 
                if (Column.IsString) {
                    if (Column.IsLongString) {
                        return new DataTypeAttribute(DataType.MultilineText);
                    } 
                    else {
                        return new DataTypeAttribute(DataType.Text); 
                    } 
                }
 
                return null;
            }

            private string GetHint(Func presentationLayerPropertyAccessor, Func hintPropertyAccessor) where T : Attribute { 
                var uiHints = Attributes.OfType();
                var presentationLayerNotSpecified = uiHints.Where(a => String.IsNullOrEmpty(presentationLayerPropertyAccessor(a))); 
                var presentationLayerSpecified = uiHints.Where(a => !String.IsNullOrEmpty(presentationLayerPropertyAccessor(a))); 

                T uiHintAttribute = presentationLayerSpecified.FirstOrDefault(a => presentationLayerPropertyAccessor(a).ToLower(CultureInfo.InvariantCulture) == "webforms" || 
                                                                                   presentationLayerPropertyAccessor(a).ToLower(CultureInfo.InvariantCulture) == "mvc") ??
                                                  presentationLayerNotSpecified.FirstOrDefault();

                return uiHintAttribute.GetPropertyValue(hintPropertyAccessor); 
            }
 
 
            public bool HtmlEncode {
                get; set; 
            }
        }

        #endregion 

        string IMetaColumn.Description { 
            get { 
                return Description;
            } 
        }

        string IMetaColumn.DisplayName {
            get { 
                return DisplayName;
            } 
        } 

        string IMetaColumn.Prompt { 
            get {
                return Prompt;
            }
        } 

        string IMetaColumn.ShortDisplayName { 
            get { 
                return ShortDisplayName;
            } 
        }

        IMetaTable IMetaColumn.Table {
            get { 
                return Table;
            } 
        } 

        IMetaModel IMetaColumn.Model { 
            get {
                return Model;
            }
        } 
    }
} 

// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
// Copyright (c) Microsoft Corporation. All rights reserved.

                        

Link Menu

Network programming in C#, Network Programming in VB.NET, Network Programming in .NET
This book is available now!
Buy at Amazon US or
Buy at Amazon UK