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

And*_*mer 54 asp.net-mvc recursion lambda extension-methods html-helper

我正在为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;
}
Run Code Online (Sandbox Code Playgroud)

谢谢!

Dar*_*rov 85

试试这样:

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());
}
Run Code Online (Sandbox Code Playgroud)

  • 我最感兴趣的是上面的这一行 - var value = ModelMetadata.FromLambdaExpression(expression,htmlHelper.ViewData).Model; 这很棒!我确实发现你的expression.Name返回null.我将它交换为指向我的MemberName方法以使其适用于ID.另外,我发现有一个TagBuilder.GenerateId()用于添加ID属性.谢谢.我将在我即将出版的书中提到你(ASP.NET MVC Cookbook - http://groups.google.com/group/aspnet-mvc-2-cookbook-review) (6认同)

Pet*_*erg 25

ModelMetadata metadata = ModelMetadata.FromLambdaExpression(expression, htmlHelper.ViewData);
Object value = metadata.Model;
String name = metadata.PropertyName;
Run Code Online (Sandbox Code Playgroud)


Ale*_*ina 10

我知道这是一个旧线程但是如果有人正在寻找它,生成id/name属性的方法也是:

System.Web.Mvc.ExpressionHelper.GetExpressionText(expression);
Run Code Online (Sandbox Code Playgroud)

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

  • 这将获取属性的名称,但不会获取其值 (2认同)

Big*_*mma 5

最简单的方法是将它包装在扩展方法中:

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

}
Run Code Online (Sandbox Code Playgroud)

所以调用语法是:

expression.Value(htmlHelper.ViewData)
Run Code Online (Sandbox Code Playgroud)