Динамически вызывать текстовое поле для отражения - PullRequest
2 голосов
/ 26 августа 2011

Конечный результат того, что я пытаюсь сделать, это построить форму динамически, отражая объект и его свойства.

Я создал методы HtmlHelper, которые вызывают TextBoxFor и CheckBoxFor и т. Д., Но теперь мне нужна помощь, чтобы выяснить, как правильно отразить свойство при передаче его в 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)

И пусть он выдаст то же самое.

UPDATE

Я повторю это, поскольку добился определенного прогресса в решении проблемы.

Я создал Expression из Expression.PropertyOrField, который создает именно то, что я ищу. Однако я не могу заставить функцию TextBoxFor принять ее.

Expression fieldExpr = Expression.PropertyOrField(Expression.Constant(model),property_name);

        return helper.TextBoxFor(Expression.Lambda<Func<TModel>>(fieldExpr, null).Compile()());

Какие-нибудь идеи о том, как правильно передать выражение в функцию?

Ответы [ 2 ]

4 голосов
/ 28 августа 2011

Хорошо, я решил эту проблему, создав лямбда-выражение, используя имя свойства и тип передаваемого объекта. Моя функция выглядит так:

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

Теперь все, что мне нужно сделать, это убедиться, что мои аннотации данных все еще работают.

0 голосов
/ 26 августа 2011

Чтобы получить свойство с помощью отражения, используйте код, подобный этому:

var prop = model_type.GetProperty(property_name);
//then in your loop:
prop.GetValue(model, null)

Или, если вы собираетесь получить свойство только от одного объекта, сделайте его одной строкой:

model_type.GetProperty(property_name).GetValue(model, null);
...