从lambda函数获取属性名称

时间:2014-08-23 12:42:45

标签: c# lambda

ASP.NET MVC以某种方式从以下结构中获取属性的名称:

@Html.LabelFor(model => model.UserName)

我也想实现这个魔法,以减少我的项目中的魔法字符串计数。你能帮帮我吗?简单的例子:

// that's how it works in my project
this.AddModelStateError("Password", "Password must not be empty"); 

// desired result
this.AddModelStateError(x => x.Password, "Password must not be empty"); 

1 个答案:

答案 0 :(得分:3)

Asp MVC的LabelFor助手需要Expression<Func<TModel, Value>>。此表达式可用于检索Func<TModel,Value>指向的属性信息,而该信息又可通过PropertyInfo.Name检索其名称。

Asp MVC然后在HTML标记上指定name属性以等于此名称。因此,如果您选择名为LabelFor Id的媒体资源,则最终会使用<label name='Id'/>

要从PropertyInfo获取Expression<Func<TModel,Value>>,您可以查看使用以下代码的this answer

public PropertyInfo GetPropertyInfo<TSource, TProperty>(
    TSource source,
    Expression<Func<TSource, TProperty>> propertyLambda)
{
    Type type = typeof(TSource);

    MemberExpression member = propertyLambda.Body as MemberExpression;
    if (member == null)
        throw new ArgumentException(string.Format(
            "Expression '{0}' refers to a method, not a property.",
            propertyLambda.ToString()));

    PropertyInfo propInfo = member.Member as PropertyInfo;
    if (propInfo == null)
        throw new ArgumentException(string.Format(
            "Expression '{0}' refers to a field, not a property.",
            propertyLambda.ToString()));

    if (type != propInfo.ReflectedType &&
        !type.IsSubclassOf(propInfo.ReflectedType))
        throw new ArgumentException(string.Format(
            "Expresion '{0}' refers to a property that is not from type {1}.",
            propertyLambda.ToString(),
            type));

    return propInfo;
}