在HtmlHelper的扩展方法中从传递的lambdaexpression式获取属性值的最简单方法是什么?

我正在为HtmlHelper写一个肮脏的小扩展方法,这样我可以像HtmlHelper.WysiwygFor(lambda)那样说,并显示CKEditor。

我目前有这个工作,但似乎比我更喜欢一些麻烦。 我希望有一个更直接的方式来做到这一点。

这是我迄今为止。

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

谢谢!

尝试像这样:

 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()); } 
 ModelMetadata metadata = ModelMetadata.FromLambdaExpression(expression, htmlHelper.ViewData); Object value = metadata.Model; String name = metadata.PropertyName; 

我知道这是一个古老的线程,但万一有人正在寻找它,生成ID /名称属性的方式也是:

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

我在扩展中使用它,从来没有任何问题。 它也适用于嵌套属性。

最简单的方法是用扩展方法将其全部包装起来:

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

所以调用语法是:

 expression.Value(htmlHelper.ViewData) 

ASP.NET MVC 3期货包括一个帮手。

Peter和BigMomma的回答都没有解决这个问题,但它将两者结合起来。 如果您从控制器方法调用此方法,则无法访问HtmlHelper实例,只需创build一个基本控制器方法,如下所示:

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

然后,像往常一样,您可以从模型元数据中读取所需的内容;

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