PropertyDescriptor.SetValue не работает в ModelBinder - PullRequest
3 голосов
/ 07 июля 2011

Я реализую пользовательский ModelBinder, где я пытаюсь установить свойство с помощью PropertyDescriptor.SetValue и не могу понять, почему оно не работает.

Для некоторых сложных свойств значение не устанавливается, но оно не выдает исключение. Свойство по-прежнему null, но для некоторых это так.

Если я получу PropertyInfo и вызову SetValue , то каждый раз будет работать нормально.

Источник Mvc из codeplex использует propertyDescriptor.SetValue(bindingContext.Model, value); для внутреннего использования, так что я думаю, что это лучший путь?

public class MyCustomBinder : DefaultModelBinder
    {
        public override object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
        {
            foreach (PropertyDescriptor property in TypeDescriptor.GetProperties(bindingContext.Model))
            {
                object value = property.GetValue(bindingContext.Model);
                // Perform custom bindings

                // Call SetValue on PropertyDescriptor (Works sometimes)
                property.SetValue(bindingContext.Model, value);
                Debug.Assert(property.GetValue(bindingContext.Model) == value, "Value not set");

                // Get PropertyInfo and call SetValue (Working)                    
                bindingContext.ModelType.GetProperty(property.Name).SetValue(bindingContext.Model, value, null);
                Debug.Assert(property.GetValue(bindingContext.Model) == value, "Value not set");
            }
            return bindingContext.Model;
        }
    }

Примечание 1. Объекты, над которыми я размышляю, отображаются с помощью nhibernate, поэтому я подозреваю, что с прокси-серверами что-то может быть.

Примечание 2. Он также не работает с DefaultModelBinder, но объекты воссоздаются, поэтому размещенные данные в порядке.

1 Ответ

2 голосов
/ 19 января 2012

Я не уверен, чего вы хотите достичь, но я игнорировал бы тот факт, что исходный код MVC использует propertyDescriptor.SetValue, если вы уже знаете, что propertyInfo.setValue дает вам то, что вы хотите.Вы пишете класс расширения, просто используйте то, что работает и является хорошим кодом:

Type modelType = bindingContext.ModelType;
foreach (PropertyInfo property in modelType.GetProperties())
{
    // ...
    property.SetValue(bindingContext.Model, value, null);
}
...