开发者

Get value from ASP.NET MVC Lambda Expression

开发者 https://www.devze.com 2023-01-18 02:55 出处:网络
I am trying to create my own HTML Helper which takes in an expr开发者_StackOverflowession (similar to the built-in LabelFor<> helper. I have found examples to obtain the value of a property when th

I am trying to create my own HTML Helper which takes in an expr开发者_StackOverflowession (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


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


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


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

精彩评论

暂无评论...
验证码 换一张
取 消