ASP.NET MVC 2 Пользовательский вопрос о привязке модели - PullRequest
1 голос
/ 19 октября 2010

Фон

У меня есть страница оплаты, где пользователь может выбрать из списка существующих способов оплаты или указать новый.В раскрывающемся списке представлены такие параметры, как:

  1. Visa - ****** 1234 (сохранено)
  2. Mastercard - ****** 9876 (сохранено)
  3. [Новая кредитная карта ...]
  4. [Новая электронная проверка ...]

Используя jQuery, я переключаю скрытые DIV, которые содержат либо информационную таблицу (в случае вариантов 1 или 2 для сохраненных способов оплаты), либо форму (в случае [новых] опций).

Я использую строго типизированный класс в качестве модели представления, которая содержит (среди простых типов) класс CreditCard и класс Check.Каждый из этих классов использует валидаторы аннотаций данных, так как они используются в других частях сайта.

Проблема

Проблема возникает, когда пользователь отправляет форму.Я хотел бы использовать привязку модели для обработки сопоставления значений POST, но мне нужно привязку и / или проверку для запуска в зависимости от того, какую опцию выбрал пользователь.Например, если пользователь выбирает вариант 1 или 2 из списка выше, я не хочу запускать проверку модели (или, возможно, даже саму привязку) для объектов CreditCard или Check.

Я исследовал возможности создания пользовательского связывателя модели с использованием IModelBinder, а также расширения DefaultModelBinder и переопределения некоторых методов.Тем не менее, я не уверен, какой метод лучше, и, если расширить DefaultModelBinder, какой метод будет подходящим для переопределения.

Логика будет довольно простой:

  • Еслипользователь выбрал один из существующих способов оплаты, проверка кредитной карты или чека не требуется.
  • Если пользователь выбрал один из вариантов создания нового метода оплаты, то только выбранный метод (CreditCard или чек)) должен быть связан и проверен

Такое ощущение, что расширение DefaultModelBinder - это то, что нужно, так как я бы хотел, чтобы большая часть тяжелой работы выполнялась фреймворком без необходимости создаватьпользовательские связующего с нуля.Однако, глядя на доступные методы для переопределения, не ясно, какой из них является лучшим:

  1. BindProperty - проблема здесь в том, что мне нужно взглянуть на одно из свойств, чтобыопределить, какие другие свойства должны быть связаны.Я не думаю, что смогу контролировать порядок, в котором связаны входящие свойства, и я не хотел бы полагаться на порядок, который они задают в форме HTML.
  2. OnModelUpdated - на данный момент этопоздно.Проверка привязки по аннотациям данных была запущена, а ModelState обновлен.Я должен был бы пройти через ModelState и удалить ошибки, которые не имеют отношения к делу.
  3. OnPropertyValidating - Сначала я думал, что это то место, где я должен искать, но даже возвращение TRUE для всех свойств (в качестве теста) приводит к тому, что ModelState содержит ошибки привязки.

У меня естьнатолкнулся на этот сценарий в других аспектах приложения и решил разделить функциональность на отдельные контроллеры / действия, чтобы упростить процесс.Однако я хотел бы лучше понять, как решать более сложные проблемы пользовательского интерфейса, особенно связанные с функциями привязки модели MVC.

Любая помощь по этому вопросу будет принята с благодарностью.

Все возможные значения хранятся в раскрывающемся списке.Используя jQuery, я переключаю форму (для нового метода оплаты) и отображение (для существующего метода)

Ответы [ 2 ]

1 голос
/ 29 октября 2010

Я решил попытаться вообще обойти привязку модели и использовать FormCollection, IValueProvider и TryUpdateModel внутри действия моего контроллера.

0 голосов
/ 19 октября 2010

Ваша проблема звучит так, чтобы быть специализированным для размещения в ModelBinder по умолчанию.

ModelBinder - это соблазнительница, которая соблазняет вас тем, что она может решить все ваши проблемы.Но затем вы начинаете объединять ModelState вместе и отправляетесь делать сумасшедшие вещи со списками вложенных объектов, и, прежде чем вы это узнаете, она дает вам документы о разводе и забирает все, кроме ваших костей.

MVC 3 обещает предоставитьболее расширяемый ModelBinder, но исходя из моего личного опыта, если только его супер-простые вещи, которые вам нужно изменить, такие как пустые поля «texbox» вместо «null», не остаются в стороне от вашей собственной реализации.

Альтернативный подход заключается виспользуйте существующую функциональность ModelBinder по частям и используйте такие вещи, как параметры метода Ignore, чтобы очистить вещи:

if( myModel.IsNewPayment )
   UpdateModel( myModel.Payment, "exclude everything else" );

Многое из того, что вы предлагаете вставить в механизм связывания моделей, на самом деле тоже бизнес-логика, которая должна быть на другом уровне,Я сделал несколько сумасшедших вещей с моим собственным ModelBinder и теперь жалею о каждой строке кода, которую я там написал.Может быть, это только я, но вы действительно нарушаете правила и полностью разрушаете «принцип единой ответственности», внедряя логику ведения бизнеса и платежей.

...