I am trying to write my first customer Html Helper extension method following the format
public static MvcHtmlString<TModel, TProperty>
MyHelperFor(this HtmlHelper<TModel> helper,
Expression<Func<TModel, TProperty>> expression)
And there seem to be several different ways to access the property name and value from the expression
var body = expression.Body as MemberExpression;
var propertyName = body.Member.Name;
var propertyInfo = typeof(TModel).getProperty(propertyName)
var propertyValue = propertyInfo.GetValue(helper.ViewData.Model);
and
var metadata = ModelMetadata.FromLambdaExpression(expression, html.ViewData);
var propertyName = metadata.PropertyName;
var propertyValue = metadata.Model;
and also
TModel model = (TModel)helper.ViewContext.ViewData.ModelMetadata.Model;
TProperty value = expression.Compile().Invoke(model);
Can somebody explain the difference between these methods? Are there any situations where one is superior to the others?
These are 3 different ways of utilizing Expression<Func<TModel, TProperty>>
. They will all give access to property value. They vary in access to the rest of the expression tree and process cost/efficiency.
Using expression.Compile().Invoke(model)
executes the expression like a function on your model :: ( u => u.name)
.
TModel model = (TModel)helper.ViewContext.ViewData.ModelMetadata.Model;
TProperty value = expression.Compile().Invoke(model);
You will get back a property or list<property>
. It is most efficient when you simply want to execute the Expression and move on.
ModelMetadata.FromLambdaExpression uses an expression of type Expression<Func<TParameter, TValue>>
as a DataDictionary
lookup.
var metadata = ModelMetadata.FromLambdaExpression(expression, html.ViewData);
var propertyName = metadata.PropertyName;
var propertyValue = metadata.Model;
This approach is more verbose and less efficient, but you have access to property value and name.
Note that ModelMetadata also gives you access to the model's annotated values such as Validators and DisplayName.
MemberExpression uses an expression to access a field / property and it's type.
var body = expression.Body as MemberExpression;
var propertyName = body.Member.Name;
var propertyInfo = typeof(TModel).getProperty(propertyName)
var propertyValue = propertyInfo.GetValue(helper.ViewData.Model);
This approach is the most verbose and least efficient, but you get have value, name and property type.
MemberExpression.Member property give access to CustomAttributes
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With