2010-09-28 16 views
8

Próbuję utworzyć własną pomocnika HTML, która pobiera wyrażenie (podobne do wbudowanego pomocnika LabelFor <> Znalazłem przykłady, aby uzyskać wartość właściwości, gdy wyrażenie jest podobny do tego:Uzyskaj wartość z ASP.NET MVC Lambda Expression

model => model.Forename 

jednak w niektóre z moich modeli, chcę uzyskać właściwości w elementach potomnych, np

model => mode.Person.Forename 

w tych przykładach, nie mogę znaleźć w każdym razie (łatwo) uzyskać wartość imię. Czy ktokolwiek może doradzić, jak powinienem być uzyskanie tej wartości.

Dzięki

Odpowiedz

14

Jeśli używasz tego samego wzoru, który używa LabelFor <> metoda, to wyrażenie będzie zawsze LambdaExpression i można po prostu go wykonać, aby uzyskać wartość.

var result = ((LambdaExpression)expression).Compile().DynamicInvoke(model); 

Generalnie, zawsze można owinąć wyrażeń generycznych w LambdaExpressions a następnie skompilować & wywołać je, aby uzyskać wartość.

Jeśli to, czego chcesz, nie jest wartością imienia, ale samym polem (aby wydrukować ciąg "imię"), jedyną opcją jest użycie formy wyrażenia. W C# 4 frameworka udostępnia klasę o nazwie ExpressionVisitor, której można użyć do tego celu, ale w przypadku wcześniejszych wersji architektury trzeba ją sami wdrożyć - patrz: http://msdn.microsoft.com/en-us/library/bb882521(VS.90).aspx

7

Poszukujesz wartości?

Dlaczego to nie zadziała?

public object GetValue<T>(Expression<Func<T>> accessor) 
    { 
     var func = accessor.Compile(); 

     return func.Invoke(); 
    } 
4

Odpowiedziałem na to osobno, ponieważ były dwie rzeczy Nie podobała mi się przyjęta odpowiedź.

  1. To nie wyjaśnia, w jaki sposób uzyskać odniesienie do modelu, który jest krytyczna informacja pisząc pomocnika niestandardowych html
  2. Jeśli wiesz, co typ delegata dla wyrażenia lambda jest do przodu to niepotrzebne jest rzutowanie go na wyrażenie Lambda i użycie DynamicInvoke. Z mojego doświadczenia w pisaniu niestandardowych pomocników mam tendencję do poznawania typów.

Przykład gdzie z góry wiedzieć, że jest przeznaczony do ekspresji lambda, która daje szereg bajtów:

public static MvcHtmlString MyHelper<TModel>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, byte[]>> expression) 
    { 

     var compiledExpression = expression.Compile(); 
     byte[] byteData = compiledExpression(htmlHelper.ViewData.Model); 

     ... 
     ... 
     ... 

     return new MvcHtmlString(.......); 
    } 
Powiązane problemy