I'm trying to use a Lambda expression and reflection to get a member hierarchical name (rather than using a text constant), to enforce compile-time errors if my control binding information is invalid.
This is in an ASP.NET MVC project, but it's not an MVC-specific question AFAIK. EDIT: Specifically, I want the following to evaluate to true:
string fullname = GetExpressionText(model => model.Locations.PreferredAreas);
"Locations.PreferredAreas" == fullname;
Instead I get a compile error:
Error 4: Cannot convert lambda expression to type 'System.Linq.Expressions.LambdaExpression' because it is not a delegate type.
Why does the parameter work in the second case below, but not the first?
// This doesn't compile:
string tb1 = System.Web.Mvc.ExpressionHelper.
GetExpressionText(model => model.Locations.PreferredAreas);
// But this does:
MvcHtmlString tb2 =
Html.TextBoxFor(model => model.Locations.PreferredAreas);
Here's the relevant code from the ASP.NET MVC Codeplex project. It looks to me like it passes the same parameter through to the same method:
// MVC extension method
public static MvcHtmlString TextBoxFor<TModel, TProperty>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TProperty>> expression, IDictionary<string, object> htmlAttributes) {
ModelMetadata metadata = ModelMetadata.FromLambdaExpression(expression, htmlHelper.ViewData);
return TextBoxHelper(
htmlHelper,
metadata,
metadata.Model,
ExpressionHelper.GetExpressionText(expression),
htmlAttributes);
}
// MVC utility method
public static string GetExpressionText(LambdaExpression expression) {
// Split apart the expression string for property/field accessors to create its name
// etc...