0

ASP.NET MVC somehow takes the names of properties from constructions like:

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

I want to implement this magic too to decrease the magic strings count in my project. Could you help me with it? Simple example:

// 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"); 
Adelf
  • 706
  • 4
  • 12

1 Answers1

3

Asp MVC's LabelFor helper takes an Expression<Func<TModel, Value>>. This expression can be used to retrieve the property info that the Func<TModel,Value> points to, which in turn can have it's name retrieved through PropertyInfo.Name.

Asp MVC then assigns the name attribute on a HTML tag to equal this name. So if you select a property with LabelFor called Id, you end up with <label name='Id'/>.

In order to get the PropertyInfo from the Expression<Func<TModel,Value>>, you could look at this answer, which uses the following code:

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;
}
Community
  • 1
  • 1
Dan
  • 10,282
  • 2
  • 37
  • 64