2010-10-18 2 views
1

фонASP.NET MVC 2 Пользовательские модели Связывание Вопрос

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

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

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

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

Проблема

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

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

логика была бы довольно просто:

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

Он чувствует, как будто расширяя DefaultModelBinder путь чтобы идти, поскольку я хотел бы, чтобы большая часть тяжелого подъема выполнялась каркасом без необходимости создания специального связующего с нуля. Однако, глядя на доступные методы, чтобы переопределить, не ясно, что является одним из лучших (ы):

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

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

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

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

ответ

1

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

0

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

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

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

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

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

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

+0

jfar, я не вижу, как это смешивает бизнес-логику с логикой представления. Я рассматриваю это как логику проверки ввода, где то, что я действительно хочу сделать, - это какая-то дифференцирующая валидация. – dotariel

+0

@ XSaint32 - дифференцирование валидации - это логическая логика для меня, проверка ввода - это не пустая строка, это допустимое дата-время, пользователь поставил цену, я пытаюсь предупредить вас здесь, дифференцируя проверку не то, что modelbinder хорош при предоставлении – jfar

+0

@jfar. То, что я имею в виду, дифференцируя проверку, заключается в том, что я не хочу, чтобы связующее устройство по умолчанию выдавало ошибки привязки для полей, которые не имеют отношения к запросу. То, как я это вижу, проверка пользователя REQUEST и взаимодействие со входом пользователя - это презентация, а не бизнес-логика. Я бы согласился с вами, если бы я пытался проверить номер кредитной карты или сравнить ее со списком заблокированных карточек. Видя, как это просто говорит: «Эй, если пользователь нажимает на вариант 1, не утруждайте себя проверкой, не ввел ли он значения для кредитной карты». – dotariel

Смежные вопросы