tutorial textboxfor net mvc expresiones example español asp asp.net-mvc recursion lambda extension-methods html-helper

asp.net-mvc - textboxfor - html label mvc c#



¿Cuál es la forma más fácil de obtener el valor de propiedad de una expresión lambda pasada en un método de extensión para HtmlHelper? (6)

Esto no es abordado por Peter ni por la respuesta de BigMomma, pero combina ambos. Si llamas esto desde un método de controlador, donde no tienes acceso a una instancia de HtmlHelper, simplemente crea un método de controlador base como este:

public ModelMetadata GetModelMetadata<TModel, TProperty>( TModel model, Expression<Func<TModel, TProperty>> expression ) { ViewData.Model = model; //model is null in Controller; you must set it here (or earlier) in order to extract values from the returned ModelMetadata. return ModelMetadata.FromLambdaExpression( expression, new ViewDataDictionary<TModel>( ViewData ) ); }

Luego puede leer lo que necesita de los metadatos del modelo como de costumbre;

var mm = GetModelMetaData( model, m => m.SomeProperty ); string name = mm.PropertyName; object value = mm.Model;

Estoy escribiendo un pequeño y sucio método de extensión para HtmlHelper para poder decir algo como HtmlHelper.WysiwygFor (lambda) y mostrar el CKEditor.

Tengo esto funcionando actualmente, pero parece un poco más engorroso de lo que preferiría. Espero que haya una manera más directa de hacer esto.

Esto es lo que tengo hasta ahora.

public static MvcHtmlString WysiwygFor<TModel, TProperty>(this HtmlHelper<TModel> helper, Expression<Func<TModel, TProperty>> expression) { return MvcHtmlString.Create(string.Concat("<textarea class=/"ckeditor/" cols=/"80/" id=/"", expression.MemberName(), "/" name=/"editor1/" rows=/"10/">", GetValue(helper, expression), "</textarea>")); } private static string GetValue<TModel, TProperty>(HtmlHelper<TModel> helper, Expression<Func<TModel, TProperty>> expression) { MemberExpression body = (MemberExpression)expression.Body; string propertyName = body.Member.Name; TModel model = helper.ViewData.Model; string value = typeof(TModel).GetProperty(propertyName).GetValue(model, null).ToString(); return value; } private static string MemberName<T, V>(this Expression<Func<T, V>> expression) { var memberExpression = expression.Body as MemberExpression; if (memberExpression == null) throw new InvalidOperationException("Expression must be a member expression"); return memberExpression.Member.Name; }

¡Gracias!


La forma más simple es envolverlo todo en un método de extensión:

public static class ExtensionMethods { public static object Value<TModel, TProperty>(this Expression<Func<TModel, TProperty>> expression, ViewDataDictionary<TModel> viewData) { return ModelMetadata.FromLambdaExpression(expression, viewData).Model; } }

Entonces la sintaxis de llamada es:

expression.Value(htmlHelper.ViewData)


Pruebe de esta manera:

public static MvcHtmlString Try<TModel, TProperty>( this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TProperty>> expression ) { var builder = new TagBuilder("textarea"); builder.AddCssClass("ckeditor"); builder.MergeAttribute("cols", "80"); builder.MergeAttribute("name", "editor1"); builder.MergeAttribute("id", expression.Name); // not sure about the id - verify var value = ModelMetadata.FromLambdaExpression( expression, htmlHelper.ViewData ).Model; builder.SetInnerText(value.ToString()); return MvcHtmlString.Create(builder.ToString()); }


Sé que este es un hilo viejo, pero por si acaso alguien lo está buscando, la forma de generar el atributo id / name también es:

System.Web.Mvc.ExpressionHelper.GetExpressionText(expression);

Estoy usando esto en mis extensiones y nunca tuve ningún problema con él. También funciona de maravilla con propiedades anidadas.



ModelMetadata metadata = ModelMetadata.FromLambdaExpression(expression, htmlHelper.ViewData); Object value = metadata.Model; String name = metadata.PropertyName;