无法获取除string之外的模型属性的自定义属性

时间:2011-11-15 16:03:33

标签: asp.net asp.net-mvc-3

我有一个模型(简化相关性),如下所示:

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帮助器类和一个Expression扩展类(都是未删节的):

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;
    }
}

在我的Razor脚本中,我进行了以下调用:

@(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"))

由于某种原因,GetAttribute方法只查找TitleName和Test的属性,这两个属性都是TitleCreateModel的字符串属性。它无法找到ReleaseDate和Wut的属性,我不知道为什么。

2 个答案:

答案 0 :(得分: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>");
}

答案 1 :(得分:1)

使用DateTime和int,Expression不是MemberExpression类型,因为拳击我相信,所以这一行:

var memberExpression = expression.Body as MemberExpression;

将返回null。

关于此主题here有一个很好的问题和答案,其中只涉及将Func泛型修改为指定的Eranga。