我正在为MVC创建一个表单生成器,我想通过以下方式模拟Razor对链接属性的处理:
builder.TextBoxFor(x => x.User.Email);
将以与Razor相同的方式产生以下内容:
<input id="User_Email" name="User.Email" type="textbox" />
以下代码适用于单个级别的链接(例如x.Email
产生Email
),但是我试图在最终属性之前检测何时有父母,然后使用递归备份链条(或至少向上一步)。
private static string GetFieldName<TModel, TProperty>(Expression<Func<TModel, TProperty>> expression)
{
var memberExpression = (MemberExpression) expression.Body;
return memberExpression.Member.Name;
}
我该如何调整以使x.User.Email
产生User.Email
而不是像现在这样产生Email
?
答案 0 :(得分:4)
您需要一点递归:
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);
}