2015-04-15 3 views
11

Ich versuche, mein erster Kunde Html Helper Extension-Methode nach dem FormatUnterschied zwischen Htmlhelper Methoden für Eigenschaften von Lambda-Ausdruck Zugriff auf

public static MvcHtmlString<TModel, TProperty> 
    MyHelperFor(this HtmlHelper<TModel> helper, 
    Expression<Func<TModel, TProperty>> expression) 

Und es scheint zu schreiben mehrere verschiedene Möglichkeiten, um den Eigenschaftsnamen und Wert zuzugreifen von der 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); 

und

var metadata = ModelMetadata.FromLambdaExpression(expression, html.ViewData); 
var propertyName = metadata.PropertyName; 
var propertyValue = metadata.Model; 

und auch

TModel model = (TModel)helper.ViewContext.ViewData.ModelMetadata.Model; 
TProperty value = expression.Compile().Invoke(model); 

Kann jemand den Unterschied zwischen diesen Methoden erklären? Gibt es Situationen, in denen die einen den anderen überlegen sind?

+0

Wenn Sie die [MVC-Quellcode] inspizieren (http://aspnetwebstack.codeplex.com/SourceControl/latest) für 'System.Web.Mvc.Html ', Sie werden sehen, dass die Helfer alle die zweite Variante benutzen -' ModelMetadata.FromLambdaExpression (expression, html.ViewData); so würde ich annehmen, dass dies der bessere Ansatz ist –

Antwort

10

Dies sind 3 verschiedene Möglichkeiten, Expression<Func<TModel, TProperty>> zu verwenden. Sie werden alle Zugang zum Wert der Immobilie geben. Sie variieren im Zugriff auf den Rest des Ausdrucksbaums und verarbeiten Kosten/Effizienz.

Die Verwendung von expression.Compile().Invoke(model) führt den Ausdruck wie eine Funktion in Ihrem Modell aus: (u => u.name).

TModel model = (TModel)helper.ViewContext.ViewData.ModelMetadata.Model; 
TProperty value = expression.Compile().Invoke(model); 

Sie erhalten eine Immobilie oder list<property>. Es ist am effizientesten, wenn Sie einfach den Ausdruck ausführen und weitergehen möchten.


ModelMetadata.FromLambdaExpression verwendet einen Ausdruck des Typs Expression<Func<TParameter, TValue>> als DataDictionary lookup.

var metadata = ModelMetadata.FromLambdaExpression(expression, html.ViewData); 
var propertyName = metadata.PropertyName; 
var propertyValue = metadata.Model; 

Dieser Ansatz ist ausführlicher und weniger effizient, aber Sie haben Zugriff auf Eigenschaft Wert und Name.

Beachten Sie, dass ModelMetadata gibt Ihnen auch die kommentierten Werte des Modells zugreifen wie Validatoren und Display.


MemberExpression verwendet einen Ausdruck ein Feld/Eigenschaft und seine Art zuzugreifen.

var body = expression.Body as MemberExpression; 
var propertyName = body.Member.Name; 
var propertyInfo = typeof(TModel).getProperty(propertyName) 
var propertyValue = propertyInfo.GetValue(helper.ViewData.Model); 

Dieser Ansatz ist die am ausführlichsten und am wenigsten effizient, aber Sie bekommen Wert, Name und Objekttyp haben.

MemberExpression.Member Eigenschaft geben Zugang zu Custom

Verwandte Themen