Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

expression.Compile() vs ModelMetadata.FromLambdaExpression

There is a common issue to write strongly-typed Html helpers. The problem is how to retrieve property name/value pair. Assume we have following Html helper declaration:

public static string DatePickerFor<TModel>(this HtmlHelper<TModel> helper, Expression<Func<TModel, DateTime?>> expression) 

There are several solutions I found: 1.

var value = expression.Compile()( helper.ViewData.Model );
string name = ExpressionHelper.GetExpressionText( expression );
string fullName = helper.ViewContext.ViewData.TemplateInfo.GetFullHtmlFieldName( name );

2.

ModelMetadata metadata = ModelMetadata.FromLambdaExpression( expression, helper.ViewData );
Object value = metadata.Model;
String name = metadata.PropertyName;

3. getting member name only using MemberExpression

string GetPropertyName<T>(Expression<Func<T>> property)
{
    var propertyInfo = (property.Body as MemberExpression).Member as PropertyInfo;
    if (propertyInfo == null)
    {
        throw new ArgumentException("The lambda expression 'property' should point to a valid Property");
    }
    return propertyInfo.Name;
}

All of them have different implementation from the first look (used Reflector to investigate) but I didn't dig deeply into.

I've stuck with so many ways to resolve issue and would like to know which solution is BETTER for different situations and WHY?

I'll be appreciate for any help

like image 682
Cheburek Avatar asked Oct 17 '10 13:10

Cheburek


1 Answers

Those solutions are used for two different contexts.

1) Is used by the views to properly prefix the html fields in preparation for model binding and has almost nothing to do with ModelMetadata. This code will provide "Customer.Addresses[0].City" in the case you need to do a sub form.

This method only cares about PropertyInfo.Name. This will never give you the contents of a [DisplayName] attribute.

2) Is what is primarily used for working with Modelmetadata. I'd use method two 99% of the time except if you need to solve #1. This will also get the metadata associated with the DataAnnotations attribute. This sill give you the content of [DisplayName].

like image 162
John Farrell Avatar answered Nov 10 '22 17:11

John Farrell