2011-11-15 60 views
0

我有一個模型(簡化了相關性)其他模特屬性:無法獲取自定義屬性這樣不是字符串

public abstract class TitleCreateModel : ICreateModel 
{ 
    [Required] 
    [MaxLength(400)] 
    public string TitleName { get; set; } 

    [Required] 
    [MaxLength(4)] 
    public DateTime ReleaseDate { get; set; } 

    [Required] 
    [MaxLength(5)] 
    public string Test { get; set; } 

    [Required] 
    [MaxLength(2)] 
    public int Wut { get; set; } 
} 

然後,我有一個自定義的HTML輔助類和表達式擴展類(包括刪節) :

public class InputHelper 
{ 
    public static HtmlString Input<T>(Expression<Func<T, Object>> expression, string id, string label) 
    { 
     var req = expression.GetAttribute<T, Object, RequiredAttribute>(); 
     var max = expression.GetAttribute<T, Object, MaxLengthAttribute>(); 
     var required = ""; 
     var maxlength = ""; 
     if(req!=null) 
     { 
      required = "req"; 
     } 
     if(max!=null) 
     { 
      maxlength = "maxlength='" + max.Length + "'"; 
     } 
     return new HtmlString("<div class=\"clearfix\"><label for=\""+id+"\">" + label + "</label>" + 
           "<div class=\"input\"><input id=\""+id+"\" class=\""+required+"\" type=\"text\" "+maxlength+"/></div></div>"); 
    } 
} 

public static class ExpressionExtensions 
{ 
    public static TAttribute GetAttribute<TIn, TOut, TAttribute>(this Expression<Func<TIn, TOut>> expression) where TAttribute : Attribute 
    { 
     var memberExpression = expression.Body as MemberExpression; 
     if (memberExpression != null) 
     { 
      var attributes = memberExpression.Member.GetCustomAttributes(typeof(TAttribute), true); 
      return attributes.Length > 0 ? attributes[0] as TAttribute : null; 
     } 
     return null; 
    } 
} 

在我的剃鬚刀劇本,我提出以下電話:

@(InputHelper.Input<string>(m => Model.Title.TitleName, "titlename", "Title Name")) 

@(InputHelper.Input<string>(m => Model.Title.Test, "testfield", "Test Field")) 

@(InputHelper.Input<int>(m => Model.Title.Wut, "tester", "Test Field 2")) 

@(InputHelper.Input<DateTime>(m => Model.Title.ReleaseDate, "release_year", "Release Year")) 

出於某種原因,T他的GetAttribute方法只找到TitleName和Test的屬性,兩者都是TitleCreateModel的字符串屬性。它無法找到ReleaseDate和Wut的屬性,我不知道爲什麼。

回答

1

修改在Input方法中使用的表達式來Expression<Func<T, TOut>> expression

public static HtmlString Input<T, TOut>(Expression<Func<T, TOut>> expression, string id, string label) 
{ 
    var req = expression.GetAttribute<T, TOut, RequiredAttribute>(); 
    var max = expression.GetAttribute<T, TOut, MaxLengthAttribute>(); 
    var required = ""; 
    var maxlength = ""; 
    if(req!=null) 
    { 
     required = "req"; 
    } 
    if(max!=null) 
    { 
     maxlength = "maxlength='" + max.Length + "'"; 
    } 
    return new HtmlString("<div class=\"clearfix\"><label for=\""+id+"\">" + label + "</label>" + 
          "<div class=\"input\"><input id=\""+id+"\" class=\""+required+"\" type=\"text\" "+maxlength+"/></div></div>"); 
} 
+0

這工作,但我不知道它爲什麼。有關於可以鏈接到的表達式的好資源嗎? –

1

隨着DateTime和int,則表達式的類型不是MemberExpression的,由於拳擊我相信,所以這行:

var memberExpression = expression.Body as MemberExpression; 

將返回空值。

關於此主題here有一個很好的問題和答案,其中只涉及修改您的Func通用指定爲Eranga。

+0

那麼爲什麼當我在Func中通用化TResult時它會工作?我對錶情完全陌生,對我來說這一切似乎都是黑魔法。 –

+0

因爲您聲明函數必須返回通用對象類型,所以需要對值類型進行額外的操作才能將該類型作爲對象進行裝箱(請參閱[裝箱文檔](http://msdn.microsoft.com/) en-us/library/yz2be5wk%28VS.80%29.aspx))所以表達式包含了額外的步驟。如果使用泛型類型,則不需要將其明確地作爲對象返回,並且該步驟將被刪除。 – Kasaku