Reputation: 2349
I'm creating a form builder for MVC and I want to simulate Razor's treatment of chained properties in the following way:
builder.TextBoxFor(x => x.User.Email);
Which would produce the following in the same manner as Razor:
<input id="User_Email" name="User.Email" type="textbox" />
The following code works for a single level of chaining (e.g. x.Email
produces Email
), but I'm trying to detect when there is a parent before the final property and then use recursion to go back up the chain (or at least go one step up).
private static string GetFieldName<TModel, TProperty>(Expression<Func<TModel, TProperty>> expression)
{
var memberExpression = (MemberExpression) expression.Body;
return memberExpression.Member.Name;
}
How can I adapt this so that x.User.Email
produces User.Email
and not just Email
as it does currently?
Upvotes: 3
Views: 161
Reputation: 37770
You need a little recursion:
private static string GetPropertyPath<TModel, TProperty>(Expression<Func<TModel, TProperty>> expression)
{
var propertyPath = new Stack<string>();
var body = (MemberExpression)expression.Body;
do
{
propertyPath.Push(body.Member.Name);
// this will evaluate to null when we will reach ParameterExpression (x in "x => x.Foo.Bar....")
body = body.Expression as MemberExpression;
}
while (body != null);
return string.Join(".", propertyPath);
}
Upvotes: 5