What is the easiest way to get the property value from a passed lambda expression in an extension method for HtmlHelper?

喜你入骨 提交于 2019-11-29 19:51:28

Try like this:

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;

I Know this is an old thread but just in case if someone is looking for it, the way to generate id / name attribute is also:

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

I'm using this in my extensions and never had any issues with it. It also works great with nested properties.

Simplest way is to wrap it all up in an extension method:

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

}

So the calling syntax is:

expression.Value(htmlHelper.ViewData)

ASP.NET MVC 3 Futures includes a helper for that.

This isn't addressed by either Peter or BigMomma's answer, but it combines both. If you're calling this from a controller method, where you don't have access to an HtmlHelper instance, just create a base controller method like this:

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

Then you can read what you need from the model metadata as usual;

var mm = GetModelMetaData( model, m => m.SomeProperty );
string name = mm.PropertyName;
object value = mm.Model;
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!