707 lines
24 KiB
C#
707 lines
24 KiB
C#
|
using System.ComponentModel;
|
||
|
using System.ComponentModel.DataAnnotations;
|
||
|
using System.Data.Spatial;
|
||
|
using System.Diagnostics;
|
||
|
using System.Diagnostics.CodeAnalysis;
|
||
|
using System.Globalization;
|
||
|
using System.Linq;
|
||
|
using System.Reflection;
|
||
|
using System.Web.DynamicData.ModelProviders;
|
||
|
using System.Web.DynamicData.Util;
|
||
|
|
||
|
namespace System.Web.DynamicData {
|
||
|
/// <summary>
|
||
|
/// Object that represents a database column used by dynamic data
|
||
|
/// </summary>
|
||
|
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;
|
||
|
}
|
||
|
|
||
|
/// <summary>
|
||
|
/// The collection of metadata attributes that apply to this column
|
||
|
/// </summary>
|
||
|
public AttributeCollection Attributes {
|
||
|
get {
|
||
|
return Metadata.Attributes;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/// <summary>
|
||
|
/// The CLR type of the property/column
|
||
|
/// </summary>
|
||
|
public Type ColumnType {
|
||
|
get {
|
||
|
if (_type == null) {
|
||
|
// If it's an Nullable<T>, work with T instead
|
||
|
_type = Misc.RemoveNullableFromType(Provider.ColumnType);
|
||
|
}
|
||
|
|
||
|
return _type;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/// <summary>
|
||
|
/// The DataTypeAttribute used for the column
|
||
|
/// </summary>
|
||
|
public DataTypeAttribute DataTypeAttribute {
|
||
|
get {
|
||
|
return Metadata.DataTypeAttribute;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/// <summary>
|
||
|
/// This column's defalut value. It is typically used to populate the field when creating a new entry.
|
||
|
/// </summary>
|
||
|
public object DefaultValue {
|
||
|
get {
|
||
|
return Metadata.DefaultValue;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/// <summary>
|
||
|
/// A description for this column
|
||
|
/// </summary>
|
||
|
public virtual string Description {
|
||
|
get {
|
||
|
//
|
||
|
return Metadata.Description;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/// <summary>
|
||
|
/// A friendly display name for this column
|
||
|
/// </summary>
|
||
|
public virtual string DisplayName {
|
||
|
get {
|
||
|
// Default to the Name if there is no DisplayName
|
||
|
return Metadata.DisplayName ?? Name;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/// <summary>
|
||
|
/// The PropertyInfo of the property that represents this column on the entity type
|
||
|
/// </summary>
|
||
|
public PropertyInfo EntityTypeProperty { get { return Provider.EntityTypeProperty; } }
|
||
|
|
||
|
/// <summary>
|
||
|
/// The FilterUIHint used for the column
|
||
|
/// </summary>
|
||
|
public string FilterUIHint {
|
||
|
get {
|
||
|
return Metadata.FilterUIHint;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/// <summary>
|
||
|
/// Does this column contain binary data
|
||
|
/// </summary>
|
||
|
public bool IsBinaryData {
|
||
|
get {
|
||
|
return ColumnType == typeof(byte[]);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/// <summary>
|
||
|
/// meant to indicate that a member is an extra property that was declared in a partial class
|
||
|
/// </summary>
|
||
|
public bool IsCustomProperty { get { return Provider.IsCustomProperty; } }
|
||
|
|
||
|
/// <summary>
|
||
|
/// Is this column a floating point type (float, double, decimal)
|
||
|
/// </summary>
|
||
|
public bool IsFloatingPoint {
|
||
|
get {
|
||
|
return ColumnType == typeof(float) || ColumnType == typeof(double) || ColumnType == typeof(decimal);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/// <summary>
|
||
|
/// 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).
|
||
|
/// </summary>
|
||
|
public bool IsForeignKeyComponent {
|
||
|
get { return Provider.IsForeignKeyComponent; }
|
||
|
}
|
||
|
|
||
|
/// <summary>
|
||
|
/// Is this column's value auto-generated in the database
|
||
|
/// </summary>
|
||
|
public bool IsGenerated { get { return Provider.IsGenerated; } }
|
||
|
|
||
|
/// <summary>
|
||
|
/// Is this column a integer
|
||
|
/// </summary>
|
||
|
public bool IsInteger {
|
||
|
get {
|
||
|
return ColumnType == typeof(byte) || ColumnType == typeof(short) || ColumnType == typeof(int) || ColumnType == typeof(long);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/// <summary>
|
||
|
/// Is this column a 'long' string. This is used to determine whether a textbox or textarea should be used.
|
||
|
/// </summary>
|
||
|
public bool IsLongString {
|
||
|
get {
|
||
|
return IsString && Provider.MaxLength >= s_longStringLengthCutoff;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/// <summary>
|
||
|
/// Is this column part if the table's primary key
|
||
|
/// </summary>
|
||
|
public bool IsPrimaryKey { get { return Provider.IsPrimaryKey; } }
|
||
|
|
||
|
/// <summary>
|
||
|
/// Is this a readonly column
|
||
|
/// </summary>
|
||
|
[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);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/// <summary>
|
||
|
/// 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).
|
||
|
/// </summary>
|
||
|
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);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/// <summary>
|
||
|
/// Does this column require a value
|
||
|
/// </summary>
|
||
|
public bool IsRequired {
|
||
|
get {
|
||
|
return Metadata.RequiredAttribute != null;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/// <summary>
|
||
|
/// Is this column a string
|
||
|
/// </summary>
|
||
|
public bool IsString {
|
||
|
get {
|
||
|
return ColumnType == typeof(string);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/// <summary>
|
||
|
/// The maximun length allowed for this column (applies to string columns)
|
||
|
/// </summary>
|
||
|
public int MaxLength {
|
||
|
get {
|
||
|
var stringLengthAttribute = Metadata.StringLengthAttribute;
|
||
|
return stringLengthAttribute != null ? stringLengthAttribute.MaximumLength : Provider.MaxLength;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/// <summary>
|
||
|
/// The MetaModel that this column belongs to
|
||
|
/// </summary>
|
||
|
public MetaModel Model { get { return Table.Model; } }
|
||
|
|
||
|
/// <summary>
|
||
|
/// The column's name
|
||
|
/// </summary>
|
||
|
public string Name { get { return Provider.Name; } }
|
||
|
|
||
|
/// <summary>
|
||
|
/// A value that can be used as a watermark in UI bound to value represented by this column.
|
||
|
/// </summary>
|
||
|
public virtual string Prompt { get { return Metadata.Prompt; } }
|
||
|
|
||
|
/// <summary>
|
||
|
/// the abstraction provider object that was used to construct this metacolumn.
|
||
|
/// </summary>
|
||
|
public ColumnProvider Provider { get; private set; }
|
||
|
|
||
|
/// <summary>
|
||
|
/// The error message used if this column is required and it is set to empty
|
||
|
/// </summary>
|
||
|
public string RequiredErrorMessage {
|
||
|
get {
|
||
|
var requiredAttribute = Metadata.RequiredAttribute;
|
||
|
return requiredAttribute != null ? requiredAttribute.FormatErrorMessage(DisplayName) : String.Empty;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/// <summary>
|
||
|
/// Is it a column that should be displayed (e.g. in a GridView's auto generate mode)
|
||
|
/// </summary>
|
||
|
[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;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/// <summary>
|
||
|
/// 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
|
||
|
/// </summary>
|
||
|
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;
|
||
|
|
||
|
//Include spatial types
|
||
|
if (ColumnType == typeof(DbGeography)) return true;
|
||
|
if (ColumnType == typeof(DbGeometry)) return true;
|
||
|
|
||
|
return false;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/// <summary>
|
||
|
/// 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
|
||
|
/// </summary>
|
||
|
public virtual string ShortDisplayName {
|
||
|
get {
|
||
|
// Default to the DisplayName if there is no ShortDisplayName
|
||
|
return Metadata.ShortDisplayName ?? DisplayName;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/// <summary>
|
||
|
/// The expression used to determine the sort order for this column
|
||
|
/// </summary>
|
||
|
public string SortExpression {
|
||
|
get {
|
||
|
return SortExpressionInternal;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
internal virtual string SortExpressionInternal {
|
||
|
get {
|
||
|
return Provider.IsSortable ? Name : string.Empty;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/// <summary>
|
||
|
/// The MetaTable that this column belongs to
|
||
|
/// </summary>
|
||
|
public MetaTable Table { get; private set; }
|
||
|
|
||
|
/// <summary>
|
||
|
/// The TypeCode of this column. It is derived from the ColumnType
|
||
|
/// </summary>
|
||
|
public TypeCode TypeCode {
|
||
|
get {
|
||
|
if (_typeCode == TypeCode.Empty) {
|
||
|
_typeCode = DataSourceUtil.TypeCodeFromType(ColumnType);
|
||
|
}
|
||
|
|
||
|
return _typeCode;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/// <summary>
|
||
|
/// The UIHint used for the column
|
||
|
/// </summary>
|
||
|
[SuppressMessage("Microsoft.Security", "CA2119:SealMethodsThatSatisfyPrivateInterfaces",
|
||
|
Justification = "Interface denotes existence of property, not used for security.")]
|
||
|
public virtual string UIHint {
|
||
|
get {
|
||
|
return Metadata.UIHint;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
#region IFieldFormattingOptions Members
|
||
|
|
||
|
/// <summary>
|
||
|
/// Same semantic as the same property on System.Web.UI.WebControls.BoundField
|
||
|
/// </summary>
|
||
|
public bool ApplyFormatInEditMode {
|
||
|
get {
|
||
|
return Metadata.ApplyFormatInEditMode;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/// <summary>
|
||
|
/// Same semantic as the same property on System.Web.UI.WebControls.BoundField
|
||
|
/// </summary>
|
||
|
public bool ConvertEmptyStringToNull {
|
||
|
get {
|
||
|
return Metadata.ConvertEmptyStringToNull;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/// <summary>
|
||
|
/// Same semantic as the same property on System.Web.UI.WebControls.BoundField
|
||
|
/// </summary>
|
||
|
public string DataFormatString {
|
||
|
get {
|
||
|
return Metadata.DataFormatString;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/// <summary>
|
||
|
/// Same semantic as the same property on System.Web.UI.WebControls.BoundField
|
||
|
/// </summary>
|
||
|
public bool HtmlEncode {
|
||
|
get {
|
||
|
return Metadata.HtmlEncode;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/// <summary>
|
||
|
/// Same semantic as the same property on System.Web.UI.WebControls.BoundField
|
||
|
/// </summary>
|
||
|
public string NullDisplayText {
|
||
|
get {
|
||
|
return Metadata.NullDisplayText;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
#endregion
|
||
|
|
||
|
/// <summary>
|
||
|
/// Build the attribute collection, later made available through the Attributes property
|
||
|
/// </summary>
|
||
|
protected virtual AttributeCollection BuildAttributeCollection() {
|
||
|
return Provider.Attributes;
|
||
|
}
|
||
|
|
||
|
/// <summary>
|
||
|
/// Perform initialization logic for this column
|
||
|
/// </summary>
|
||
|
internal protected virtual void Initialize() { }
|
||
|
|
||
|
/// <summary>
|
||
|
/// 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.
|
||
|
/// </summary>
|
||
|
public void ResetMetadata() {
|
||
|
_metadata = null;
|
||
|
}
|
||
|
|
||
|
/// <summary>
|
||
|
/// Shows the column name. Mostly for debugging purpose.
|
||
|
/// </summary>
|
||
|
[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<DisplayAttribute>();
|
||
|
DataTypeAttribute = Attributes.FirstOrDefault<DataTypeAttribute>() ?? GetDefaultDataTypeAttribute();
|
||
|
DescriptionAttribute = Attributes.FirstOrDefault<DescriptionAttribute>();
|
||
|
DefaultValueAttribute = Attributes.FirstOrDefault<DefaultValueAttribute>();
|
||
|
DisplayNameAttribute = Attributes.FirstOrDefault<DisplayNameAttribute>();
|
||
|
RequiredAttribute = Attributes.FirstOrDefault<RequiredAttribute>();
|
||
|
ScaffoldColumnAttribute = Attributes.FirstOrDefault<ScaffoldColumnAttribute>();
|
||
|
StringLengthAttribute = Attributes.FirstOrDefault<StringLengthAttribute>();
|
||
|
|
||
|
UIHint = GetHint<UIHintAttribute>(a => a.PresentationLayer, a => a.UIHint);
|
||
|
FilterUIHint = GetHint<FilterUIHintAttribute>(a => a.PresentationLayer, a => a.FilterUIHint);
|
||
|
|
||
|
EditableAttribute = Attributes.FirstOrDefault<EditableAttribute>();
|
||
|
IsReadOnly = Attributes.GetAttributePropertyValue<ReadOnlyAttribute, bool>(a => a.IsReadOnly, false);
|
||
|
|
||
|
var displayFormatAttribute = Attributes.FirstOrDefault<DisplayFormatAttribute>() ??
|
||
|
(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<T>(Func<T, string> presentationLayerPropertyAccessor, Func<T, string> hintPropertyAccessor) where T : Attribute {
|
||
|
var uiHints = Attributes.OfType<T>();
|
||
|
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;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|