从 HtmlHelper 的扩展方法中传递的 lambda 表达式中获取属性值的最简单方法是啥?
Posted
技术标签:
【中文标题】从 HtmlHelper 的扩展方法中传递的 lambda 表达式中获取属性值的最简单方法是啥?【英文标题】:What is the easiest way to get the property value from a passed lambda expression in an extension method for HtmlHelper?从 HtmlHelper 的扩展方法中传递的 lambda 表达式中获取属性值的最简单方法是什么? 【发布时间】:2011-02-20 06:22:56 【问题描述】:我正在为 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;
谢谢!
【问题讨论】:
我测试了你的 Getvalue 方法,当助手是一个选择列表时得到了很好的结果。在这种情况下,这里的其他方法都失败了。 【参考方案1】:试试这样:
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());
【讨论】:
我最感兴趣的是上面的这一行 - var value = ModelMetadata.FromLambdaExpression( expression, htmlHelper.ViewData ).Model;效果很好!我确实发现您的 expression.Name 返回 null。我将其交换为指向我的 MemberName 方法以使其适用于 ID。另外,我发现有一个 TagBuilder.GenerateId() 用于添加 ID 属性。谢谢。我一定会在我即将出版的书中提到你(ASP.NET MVC Cookbook - groups.google.com/group/aspnet-mvc-2-cookbook-review) 嘿达林,你能解释一下这行吗?var value = ModelMetadata.FromLambdaExpression( expression, htmlHelper.ViewData ).Model;
【参考方案2】:
ModelMetadata metadata = ModelMetadata.FromLambdaExpression(expression, htmlHelper.ViewData);
Object value = metadata.Model;
String name = metadata.PropertyName;
【讨论】:
这对我有用,并通过 PropertyName 正确获取属性名称,其中 expression.Name 返回 null。编辑添加 - 我正在运行 MVC5 以防万一【参考方案3】:我知道这是一个旧线程,但以防万一有人在寻找它,生成 id / name 属性的方法也是:
System.Web.Mvc.ExpressionHelper.GetExpressionText(expression);
我在我的扩展程序中使用它并且从未遇到任何问题。它也适用于嵌套属性。
【讨论】:
这将获得属性的名称,而不是它的值【参考方案4】:最简单的方法是将其全部包装在一个扩展方法中:
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)
【讨论】:
【参考方案5】:ASP.NET MVC 3 Futures 包含一个帮助器。
【讨论】:
【参考方案6】:彼得或 BigMomma 的回答都没有解决这个问题,但它结合了两者。如果您从一个控制器方法调用它,而您无法访问 HtmlHelper 实例,则只需创建一个基本控制器方法,如下所示:
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;
【讨论】:
以上是关于从 HtmlHelper 的扩展方法中传递的 lambda 表达式中获取属性值的最简单方法是啥?的主要内容,如果未能解决你的问题,请参考以下文章
查找HTMLHelper,URLHelper和AJAXHelper类型的所有扩展方法
在 ASP.net core mvc 3.1 中的 HtmlHelper 扩展方法中使用 DataAnnotation 本地化器
.NET MVC3中扩展一个HtmlHelper方法CheckBoxList
ASP.Net MVC开发基础学习笔记:二HtmlHelper与扩展方法