Получить значение из лямбда-выражения ASP.NET MVC - PullRequest
8 голосов
/ 28 сентября 2010

Я пытаюсь создать свой собственный HTML Helper, который принимает выражение (аналогично встроенному помощнику LabelFor <>. Я нашел примеры для получения значения свойства, когда выражение похоже на это:

model => model.Forename

Однако в некоторых моих моделях я хочу получить свойства в дочерних элементах, например,

model => mode.Person.Forename

. В этих примерах я никак не могу найти (легко) получить значениеИмя. Может кто-нибудь посоветовать, как мне получить это значение.

Спасибо

Ответы [ 3 ]

14 голосов
/ 28 сентября 2010

Если вы используете тот же шаблон, что и метод LabelFor <>, то выражение всегда будет выражением LambdaExpression, и вы можете просто выполнить его, чтобы получить значение.

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

Как правило, вы можетевсегда оборачивайте обобщенные выражения в LambdaExpressions, а затем компилируйте и вызывайте их, чтобы получить значение.

Если то, что вы хотите, это не значение Forename, а само поле (например, распечатать строку «Forename») тогда ваш единственный вариант - это использовать какую-то форму экспрессионной ходьбы.В C # 4 платформа предоставляет класс ExpressionVisitor, который может использоваться для этого, но для более ранних версий платформы вы должны реализовать его самостоятельно - см .: http://msdn.microsoft.com/en-us/library/bb882521(VS.90).aspx

7 голосов
/ 28 сентября 2010

Вы ищете значение?

Почему бы не сработать?

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

        return func.Invoke();
    }
4 голосов
/ 12 мая 2015

Я ответил на это отдельно, потому что в принятом ответе мне не нравились две вещи.

  1. Это не объясняет, как получить ссылку на модель, которая является критическойчасть информации при написании пользовательского помощника html
  2. Если вы заранее знаете, какой тип делегата для лямбда-выражения, нет необходимости приводить его к лямбда-выражению и использовать DynamicInvoke.По своему опыту написания пользовательских помощников я обычно заранее знаю типы.

Пример, где я знаю заранее, что он разработан для лямбда-выражения, которое дает массив байтов:

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(.......);
    }
...