user460667
user460667

Reputation: 1940

Get value from ASP.NET MVC Lambda Expression

I am trying to create my own HTML Helper which takes in an expression (similar to the built-in LabelFor<> helper. I have found examples to obtain the value of a property when the expression is similar to this:

model => model.Forename

However, in some of my models, I want to obtain properties in child elements, e.g.

model => mode.Person.Forename

In these examples, I cannot find anyway to (easily) obtain the value of Forename. Can anybody advise on how I should be getting this value.

Thanks

Upvotes: 10

Views: 9488

Answers (3)

Alan Macdonald
Alan Macdonald

Reputation: 1900

I've answered this separately because there was two things I didn't like about the accepted answer.

  1. It doesn't explain how to get a reference to the model which is a critical piece of information when writing a custom html helper
  2. If you know what the delegate type for the lambda expression is up front it is unneccessary to cast it to the Lambda expression and use DynamicInvoke. In my experience of writing custom helpers I tend to know up front the types.

Example where I know up front it is designed for a lambda expression that yields a byte array:

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

Upvotes: 6

AHM
AHM

Reputation: 5225

If you are using the same pattern that the LabelFor<> method uses, then the expression will always be a LambdaExpression and you can just execute it to get the value.

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

Generally, you can always wrap generic expressions in LambdaExpressions and then compile & invoke them to get the value.

If what you want isn't the value of Forename, but the field itself (fx. to print out the string "Forename") then your only option is to use some form of expressionwalking. In C#4 the framework provides a class called ExpressionVisitor that can be used for this, but for earlier versions of the framework you have to implement it yourself - see: http://msdn.microsoft.com/en-us/library/bb882521(VS.90).aspx

Upvotes: 16

John Farrell
John Farrell

Reputation: 24754

Your looking for the value?

Why wouldn't this work?

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

        return func.Invoke();
    }

Upvotes: 7

Related Questions