从 lambda 函数获取属性名称

本文关键字:属性 获取 lambda 函数 | 更新日期: 2023-09-27 18:19:21

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"); 

从 lambda 函数获取属性名称

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

然后,Asp MVC 将 HTML 标记上的 name 属性分配给与此名称相等。因此,如果您选择具有LabelFor的属性,称为 Id ,最终会得到 <label name='Id'/> .

为了从Expression<Func<TModel,Value>>中获取PropertyInfo,你可以看看这个答案,它使用以下代码:

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