I'm trying to write a strongly typed helper which would be something like this:
Html.Lookup(x => x.FooId);
for now I have this:
public static MvcHtmlString Lookup<T,TReturn>(this HtmlHelper<T> html, Func<T, TReturn> expression)
{
     // get string "FooId" here
}
Anybody knows how to get this ?
Yet another code.
public MvcHtmlString Lookup<T, TReturn>(this HtmlHelper<T> html, Expression<Func<T, TReturn>> expression)
{
  return MvcHtmlString.Create(ExpressionHelper.GetExpressionText(expression));
}
Use ExpressionHelper class. Func is delegate, Expression is generate ExpressionTree at compile time. Expression.Compile() return delegate, but Func don't get ExpressionTree at runtime.
public static class ExpressionsExtractor
{
    public static string Lookup<T, TProp>(this HtmlHelper<T> html, Expression<Func<T, TProp>> expression)
    {
        var memberExpression = expression.Body as MemberExpression;
        if (memberExpression == null)
            return null;
        return memberExpression.Member.Name;
    }
}
You would then call it with:
var propName = Html.Lookup(x => x.FooId);
                        Currently using this class when I need this functionality outside of web project where System.Web.Mvc reference shouldn't exist:
namespace Interreg.Domain{
  using System;
  using System.Linq.Expressions;
  public class PropertyName{
    public static string For<T>(
      Expression<Func<T,object>> expression){
      var body=expression.Body;
      return GetMemberName(body);
    }
    public static string For(
      Expression<Func<object>> expression){
      var body=expression.Body;
      return GetMemberName(body);
    }
    public static string GetMemberName(
      Expression expression){
      if(expression is MemberExpression){
        var memberExpression=(MemberExpression)expression;
        if(memberExpression.Expression.NodeType==
           ExpressionType.MemberAccess)
          return GetMemberName(memberExpression.Expression)+"."+memberExpression.Member.Name;
        return memberExpression.Member.Name;
      }
      if(expression is UnaryExpression){
        var unaryExpression=(UnaryExpression)expression;
        if(unaryExpression.NodeType!=ExpressionType.Convert)
          throw new Exception(string.Format("Cannot interpret member from {0}",expression));
        return GetMemberName(unaryExpression.Operand);
      }
      throw new Exception(string.Format("Could not determine member from {0}",expression));
    }
  }
}
Good thing about this one is - it does not lose dots when going deeper than just one level.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With