2010-09-23 20 views
10

Sto cercando di scrivere un aiutante fortemente tipizzato che sarebbe qualcosa di simile:Get stringa nome della proprietà da espressione

Html.Lookup(x => x.FooId); 

per ora ho questo:

public static MvcHtmlString Lookup<T,TReturn>(this HtmlHelper<T> html, Func<T, TReturn> expression) 
     { 
      // get string "FooId" here 
     } 

nessuno sa come per ottenere questo?

+0

possibile duplicato [Ottenere la proprietà, come una stringa, da un'espressione >] (http://stackoverflow.com/questions/2789504/get-the-property-as-a-string-from-an-expressionfunctmodel-tproperty) –

+1

Perché stai reinventando 'ViewData.ModelMetadata'? –

+0

@Craig Stuntz In realtà non capisco cosa intendi, voglio solo creare un helper fortemente tipizzato – Omu

risposta

22
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; 
    } 
} 

Si potrebbe quindi chiamare con:

var propName = Html.Lookup(x => x.FooId); 
+0

penso che questo dovrebbe funzionare, ma sembra che io non abbia dichiarato correttamente la mia espressione o qualcosa perchè non posso usarlo io volevo – Omu

+0

Ho modificato la mia domanda ora è come dovrebbe – Omu

+0

Modificata la risposta per abbinare la tua domanda aggiornata. –

12

Ancora un altro codice.

public MvcHtmlString Lookup<T, TReturn>(this HtmlHelper<T> html, Expression<Func<T, TReturn>> expression) 
{ 
    return MvcHtmlString.Create(ExpressionHelper.GetExpressionText(expression)); 
} 

Utilizzare la classe ExpressionHelper. Func is delegate, Expression è generare ExpressionTree in fase di compilazione. Expression.Compile() return delegate, ma Func non ottiene ExpressionTree in fase di runtime.

+1

, preferisco questo, perché lo stesso framework Mvc lo usa. –

+0

Anche questo restituisce "Class.PropertName" contrariamente alla risposta accettata sopra. –

8

Attualmente utilizzando questa classe quando ho bisogno di questa funzionalità al di fuori del progetto web dove System.Web.Mvc di riferimento non dovrebbe esistere:

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

Cosa buona di questo è - non perde punti quando si va più profondo di un solo livello.

0

un po 'tardi, ma sto postando una soluzione semplice che sta lavorando per me in Net 4. E' la gestione per i tipi di valore sulla linea 4

public PropertyInfo GetPropertyInfo<TSource>(Expression<Func<TSource, object>> propertyLambda) { 
     var member = propertyLambda.Body as MemberExpression; 
     if (member == null) {// value types return Convert(x.property) which can't be cast to MemberExpression 
      var expression = propertyLambda.Body as UnaryExpression; 
      member = expression.Operand as MemberExpression; 
     } 
     return member.Member as PropertyInfo; 
    } 
Problemi correlati