Привязка модели - тип времени выполнения - PullRequest
2 голосов
/ 02 марта 2012

Я недавно обнаружил, что если я сказал:

object latestPosts = new MyApp.Models.LatestPosts();
TryUpdateModel(latestPosts);

Объект latestPosts не обновляется.Это связано с обнаруженной проблемой здесь .Использование обходного пути решило проблему.Однако, если я перемещаю latestPosts в свойство (называемое параметрами) существующего типа (например, Widget), это не обновляет модель.Например,

var widget = new Widget();
MyTryUpdateModel(widget, "Widget", null, null, ValueProvider); // LatestPosts doesn't update

Но работает следующее:

MyTryUpdateModel(widget.Parameters, "Widget.Parameters", null, null, ValueProvider);

Редактировать: Вот класс Widget:

public class Widget {        
    [Required, StringLength(100)]
    public virtual string Name { get; set; }

    private object _parameters;
    public virtual object Parameters {
        get {
            // Code removed for brevity
            if (_parameters == null)
                _parameters = new MyApp.Models.LatestPosts();

            return _parameters;
        } set { _parameters = value; }
    }
}

А вот класс LatestPosts:

public class LatestPosts {
    public int NumPosts { get; set; }
}

Я не могу понять, почему начальная MyTryUpdateModel не работала для обновления всего виджета, поскольку он должен обрабатывать сложные типы.Буду признателен, если кто-нибудь сможет пролить свет на этот вопрос.

Спасибо

1 Ответ

0 голосов
/ 08 марта 2012

Я объясню, почему оригинальный TryUpdateModel не работает и почему «исправленный TryUpdateNode» не работает в вашем случае. Я являюсь координатором Mvc Controls Toolkit, который содержит сложный пользовательский связыватель моделей, поэтому мы приобрелиглубокое знание Model Binder и проблем, стоящих за ним.

Default TryUpdateModel: он просто вызывает DefaultModelBinder. Теперь определение типа во время выполнения на основе информации, полученной в процессе связывания модели, является рискованным, поскольку такая информация поступает изклиент и может подвергаться манипулированию со стороны злоумышленника, который, таким образом, может заставить связыватель модели создать экземпляр типа, который он решил .... очень рискованно ... Он может использовать это, чтобы заставить связыватель модели выполнить нежелательное вредоносное действиекод, который находится в конструкторе типа «поддельный». Таким образом, общий выбор дизайна заключается в том, что ВСЕ ТИПЫ, используемые связывателем модели, ДОЛЖНЫ БЫТЬ ОПРЕДЕЛЕНЫ В СКОРОСТЬ ВРЕМЕНИ

MyTryUpdateModel: он просто определяет тип корневой моделипо телефонуg GetType, а затем используйте эту информацию для вызова связывателя модели по умолчанию для этого типа.Однако, за исключением этого начального «запуска», связыватель моделей работает как обычно ... то есть ... тип свойств корневой модели, НЕ ПОЛУЧАЕТСЯ С GetType или с информацией о времени выполнения, а просто проверяеттип свойства корневой модели ... который в вашем случае является объектом ... это означает отсутствие информации.

В связывателе пользовательской модели по умолчанию Mvc Controls Toolkit есть инструменты для определения типа во время выполнения... но не ВСЕ ТИПЫ .. потому что это подвергает риску attcks ... типы, которые являются подтипами "безопасных" типов .. например, типы экземпляров, которые реализуют Интерфейс.

...