2009-10-23 3 views
1

Вот простая проблема: пользователи хотят редактировать продукты в виде сетки: выберите и нажмите «Добавить», выберите и нажмите «Добавить» ... и они видят обновленный список продуктов ... затем нажмите «Готово», и заказ должен быть сохранен.ASP.NET MVC: где сохранить объект, редактируемый пользователем

Однако для каждого «Добавить» есть, чтобы перейти на сервер, поскольку он включает проверку на стороне сервера. Более того, проверка выполняется внутри объекта домена (скажем, порядка), то есть для проверки необходимо вызвать order.Add (продукт), а затем порядок решает, может ли он добавить продукт.

Проблема заключается в том, что если я добавляю продукты на заказ, они сохраняют изменения, поэтому даже если пользователи не нажмут «Готово», изменения все равно будут там!

ОК, я, вероятно, не должен изменить заказ, пока пользователи не нажмут кнопку «Готово». Однако, как я могу проверить продукт? Это должно быть сделано субъектом заказа - если продукт уже добавлен, если продукт не конфликтует с другими продуктами и т. Д.

Другая проблема заключается в том, что я должен добавить продукт на заказ и «перестроить представление/HTML» на основе на его новом состоянии (так как он может сильно измениться). Но если я не буду сохранять изменения порядка, следующий Add будет начинаться с одного и того же порядка каждый раз, а не с обновленного. То есть, мне нужно как-то отслеживать изменения в заказе.

Я вижу несколько решений:

  1. Каждый раз, когда пользователь нажмите кнопку Добавить, восстановить порядок из базы данных, а также добавлять все новые продукты (со страницы), но не сохраняется, просто вернуть View (заказ) , Проблема в том, что я не могу перенаправлять из POST/Edit в GET/Edit - потому что все данные существуют только в данных POST, а GET - потерять. Это означает, что страница обновления не работает красиво (F5 и вы получаете дублированный запрос, не говоря уже о диалоговом окне браузера)).
    • Хм, я думал, что может сделать перенаправление на GET с использованием TempData (и помощника MvcContrib). Поэтому после того, как POST to/Edit обрабатывает бизнес-логику, получает новые данные для просмотра и делает RedirectToAction <> (данные) из MvcContrib, который передает данные через TempData. Но поскольку TempDate - это ... temp ... после F5 все данные теряются. Не работает. Проклятые данные должны храниться где-то, так или иначе.
  2. Храните «редактируемый объект» в сеансе с данными POST (заказ, информация о новых продуктах). Это также может быть база данных. Вид «текущий элемент - тип страницы». Таким образом, страница получит идентификатор заказа и в настоящее время добавит продукты из этого хранилища. Но редактирование с нескольких страниц проблематично. И мне не нравится хранить временные/текущие объекты в сеансе.
  3. Маркировка продуктов как «подтвержденных» - если мы делаем/заказываем/показываем, мы сначала очищаем все неподтвержденные продукты от заказа. Уродливая и грязная логика.
  4. Сделайте копию заказа - временный - и сделайте/отредактируйте работу с ним. Подтверждение переместит изменения из временного порядка в постоянное. Много уродливой работы.
  5. Возможно, что-то волшебство AJAX? То есть Кнопка «Добавить» не перезагружает страницу, а просто отправит новые + уже добавленные продукты на сервер, сервер будет проверять как заказ.Add (продукты + новый продукт), но не будет сохранить изменения, просто вернет обновленную информацию о заказе, построить сетку. Но Refresh/F5 убьет всю введенную пользователем информацию.
  6. Что еще?

Является ли эта проблема распространенной? Как вы решаете подобные?Каковы лучшие практики?

+0

Я оставил дополнительный комментарий в ответ на ваши последние комментарии. – AaronSieb

ответ

0

Это зависит от того, как вы реализуете свои объекты/проверку, но ваш вариант номер 5, вероятно, является лучшей идеей. Если AJAX не ваша вещь, вы можете сделать то же самое, написав соответствующие данные уже добавленных, но не сохраненных записей в скрытые поля.

Другими словами, поток заканчивается что-то вроде этого:

  1. Пользователь вводит элемент.

  2. Товар отправлен на сервер и подтвержден. Вид возвращается с данными, введенными пользователем в скрытых полях.

  3. Пользователь вводит второй элемент.

  4. Товар отправляется на сервер, и оба элемента проверяются. Представление возвращается с данными для обоих элементов в скрытых полях.

  5. т.д.

До сих пор, как F5/Обновить убийство введенных данных ... По моему опыту, это не слишком большая проблема. Более насущной проблемой являются кнопки назад/вперед, которым нужно управлять с помощью чего-то вроде Really Simple History.

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

  1. Упорство записей в базе данных, связанных с текущим пользователем каким-либо образом.
  2. Сохранять записи на сессии.
  3. Сохранять записи в строке запроса.

Это единственные доступные места хранения, которые сохраняются как при перенаправлении, так и при обновлении.

+0

Ajax - это мое дело, и мне не нужно скрывать - мне действительно нужно отображать данные пользователю (т. Е. Пользователь вводил Product1, мне нужно отображать также отношения цены и отношения к другим продуктам в заказе). Ну, может быть, F5 не проблема, мне нужно обсудить это с клиентами. Но в целом это было бы раздражать (по крайней мере, для меня). Я обновляю вопрос так, как вы предлагали (сохраняете). – queen3

+0

Кроме того, я немного смущен вашими ссылками на то, что вы не можете нажать кнопку обновления, раздражающую. Регулярно ли вы обновляете страницы, когда вы на полпути заполняете форму? – AaronSieb

+0

Извините, я должен упустить некоторый момент об этих скрытых полях ... использование полей для хранения данных - это вариант № 1, который я перечислял. Проблема в том, что F5 снова отправляет последний запрос на сервер, что приведет к дублированию данных. Хм, я думаю, что могу обойтись с TempData (см. Обновление). Что касается освежения, представьте, что вы случайно нажали на нее и потеряли все введенные данные (с AJAX); или вы используете его для «сброса» формы - как я часто это делаю, - но вместо этого вы получите диалоговое окно и дублированный POST на сервер - раздражает. – queen3

0

Если бы я был вами, я бы придумал что-то похожее на вариант 5. И поскольку вы говорите, что вам удобно с Ajax, вы можете попробовать это. Но прежде чем вы это сделаете, вы должны : переместите логику проверки вне метода Order.Add(). Возможно, вы можете перенести его на другую публичную функцию под названием Validate(), которая возвращает bool. И вы все равно можете вызвать тот же метод Validate() в методе Add(), тем самым сделав необходимую проверку, прежде чем добавлять заказ.

  1. Попробуйте выполнить проверку на стороне клиента. Если вы используете jQuery, вы можете использовать плагин проверки jquery. Но, если это невозможно по какой-либо причине (например, когда вам нужно проверить данные по базе данных). Вы должны сделать свою проверку на стороне сервера и просто вернуть объект JSON с булевым флагом «success» и необязательным сообщением, просто чтобы отметить, что данные действительны. Вы позволили бы пользователю добавлять новый продукт только в том случае, если предыдущий Порядок был действительным.
  2. И когда пользователь нажимает «Готово», отправьте продукт на сервер и повторите проверку, но сохраните заказ в этом раунде.

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

+0

Это не просто проверка, это сущность изменений ... скажем, когда вы добавляете продукт, другие (добавленные) продукты имеют счетчик «приятелей», пересчитанный ... там должен быть вызовом сервера для этого, так как не рекомендуется переписывать бизнес-правила на клиентских сценариях. – queen3

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