我尝试做的最终结果是通过反映对象及其属性来动态构建表单。
我已经创建了调用TextBoxFor和CheckBoxFor等的HtmlHelper方法,但现在我需要帮助确定如何在将属性传递给Html.TextBoxFor时正确反映该属性
这是辅助方法:
public static MvcHtmlString FormTextBox<TModel>(this HtmlHelper<TModel> helper, String id, String property_name, object model, RouteValueDictionary attributes)
{
Type model_type = model.GetType();
return helper.TextBoxFor(model_object => model_type.InvokeMember(property_name, BindingFlags.ExactBinding | BindingFlags.GetProperty, null, model, null));
}
但它在返回时会出现此错误代码:
模板只能用于字段访问,属性访问,单维数组索引或单参数自定义索引器表达式。
基本上我想采取的是:
@Html.TextBoxFor(model => model.Name)
把它变成这个:
@FormHelpers.FormTextBox("Name", model)
让它输出同样的东西。
更新
我将重申这一点,因为我在解决问题方面取得了一些进展。
我已经从Expression.PropertyOrField创建了一个表达式,它可以创建我正在寻找的内容。但是我无法让TextBoxFor函数接受它。
Expression fieldExpr = Expression.PropertyOrField(Expression.Constant(model),property_name);
return helper.TextBoxFor(Expression.Lambda<Func<TModel>>(fieldExpr, null).Compile()());
关于如何将Expression正确传递给函数的任何想法?
答案 0 :(得分:4)
好的,我通过使用属性名称和传入的对象的类型构建lambda表达式来解决这个问题。我的函数如下所示:
ParameterExpression fieldName = Expression.Parameter(typeof(object), property_name);
Expression fieldExpr = Expression.PropertyOrField(Expression.Constant(model), property_name);
Expression<Func<TModel, object>> exp = Expression.Lambda<Func<TModel, object>>(fieldExpr, fieldName);
return helper.TextBoxFor(exp);
示例:
@{ Name myname = new Name();}
@Html.FormTextBox("first", myname)
fieldName为左侧(第一个)构建表达式,然后fieldExpr使用类名和属性名构建表达式的主体。
exp最终看起来像这样:
first => value(DynamicForm.Models.Name).first
现在我需要做的就是确保我的数据注释仍然有效。
答案 1 :(得分:0)
要使用反射获取属性,请使用以下代码:
var prop = model_type.GetProperty(property_name);
//then in your loop:
prop.GetValue(model, null)
或者,如果您只是从一个对象获取属性,请将其设为一行:
model_type.GetProperty(property_name).GetValue(model, null);