2012-02-13 17 views
4

我正在尋找一種有效的方法來自動格式化實體中的數據字段 - 理想情況下使用屬性。使用C#中的屬性格式化字段 - DisplayFormatAttribute?

我們需要從數據模型生成一個PDF文件。我們希望確保可交付成果的一致性,所以我們希望將某些格式化規則應用於某些數據字段(日期,電話號碼,郵政編碼等)。當然,我可以編寫自定義屬性和格式化代碼,但我寧願不重新發明輪子。我看到使用DataAnnotations的許多承諾(尤其是DisplayFormat屬性),但我似乎無法找到任何可以使用這些屬性的內置類。

如何在非UI(即非MVC)上下文中執行此操作?

這裏是我們要找的是什麼一個例子:

public class MyDataModel 
{ 
    [PhoneNumber] 
    public string PhoneNumber { get; set; } 

    public void FormatData() 
    { 
     //Invoke some .NET or other method changes the value of PhoneNumber into a desired format, i.e. (888)555-1234 based on its decorations. 
    } 
} 

我也開到創建數據的「視圖」,而不是更新原始對象的解決方案,那就是:

MyDataModel formatted = original.FormatData(); 

無論需要最少量的代碼是理想的。

回答

0

您可以使用MaskedTextBox

MaskedTextBox mtb = new MaskedTextBox(); 
mtb.Mask = "(999) 000-0000"; 
inputString=Regex.Replace(inputString, @"\D+", ""); 
mtb.Text = inputString; 

然後,你檢查的文本...

string s = mtb.Text; //s = "(204) 867-5309"

你可以做同樣的事,郵政編碼,或任何就像是一個預測的格式那。

也許不是超級乾淨,但它確實是快速和容易。

編輯: 我添加了一個正則表達式來確保只有數字用作輸入,以防用戶在輸入時使用連字符或括號。

+1

什麼是MaskedTextBox中?這如何幫助Web項目之外的OP? – jrummell 2012-02-13 17:46:54

+0

MaskedTextBox是System.Windows.Forms的一部分。它將任何格式化的樣式,即掩碼設置爲輸入文本,這似乎是OP想要的。它不應該與Web項目有任何關係。 – Brad 2012-02-13 18:01:19

2

您必須使用反射才能讀取某個類型屬性的屬性。 This answer提供了一些應該有所幫助的擴展方法。這是一個MVC的問題,但它會工作外MVC的還有:


public static T GetAttribute<T>(this MemberInfo member, bool isRequired) 
    where T : Attribute 
{ 
    var attribute = member.GetCustomAttributes(typeof(T), false).SingleOrDefault(); 

    if (attribute == null && isRequired) 
    { 
     throw new ArgumentException(
      string.Format(
       CultureInfo.InvariantCulture, 
       "The {0} attribute must be defined on member {1}", 
       typeof(T).Name, 
       member.Name)); 
    } 

    return (T)attribute; 
} 

public static string GetPropertyDisplayName<T>(Expression<Func<T, object>> propertyExpression) 
{ 
    var memberInfo = GetPropertyInformation(propertyExpression.Body); 
    if (memberInfo == null) 
    { 
     throw new ArgumentException(
      "No property reference expression was found.", 
      "propertyExpression"); 
    } 

    var attr = memberInfo.GetAttribute<DisplayNameAttribute>(false); 
    if (attr == null) 
    { 
     return memberInfo.Name; 
    } 

    return attr.DisplayName; 
} 

public static MemberInfo GetPropertyInformation(Expression propertyExpression) 
{ 
    Debug.Assert(propertyExpression != null, "propertyExpression != null"); 
    MemberExpression memberExpr = propertyExpression as MemberExpression; 
    if (memberExpr == null) 
    { 
     UnaryExpression unaryExpr = propertyExpression as UnaryExpression; 
     if (unaryExpr != null && unaryExpr.NodeType == ExpressionType.Convert) 
     { 
      memberExpr = unaryExpr.Operand as MemberExpression; 
     } 
    } 

    if (memberExpr != null && memberExpr.Member.MemberType == MemberTypes.Property) 
    { 
     return memberExpr.Member; 
    } 

    return null; 
} 

用法是:

string displayName = ReflectionExtensions.GetPropertyDisplayName<SomeClass>(i => i.SomeProperty); 
+0

反射會起作用,但如果可能的話,我真的在尋找內置的東西。例如,在.NET框架中必須有內置的東西來實現這一點,因爲DynamicData似乎是自動完成的,但我似乎無法找到負責轉換的類。我想他們會公開暴露這些有用的類? – 2012-02-13 22:42:53

相關問題