Действие MVC 3 на другом контроллере, но нужна ViewModel

#asp.net-mvc #model #controllers #tempdata

#asp.net-mvc #Модель #контроллеры #tempdata

Вопрос:

Я ищу наилучший из возможных способов решения следующей проблемы: у меня есть страница поиска с различными критериями, которые можно выбрать, которые доступны в SearchViewModel. Теперь поиск возвращает список результатов поиска, которые являются продуктами. Их можно добавить непосредственно в корзину. Теперь проблема в том, что действие для добавления элемента в корзину выполняется в BasketController, а не в SearchController. Когда пользователь нажимает на него, он возвращается на страницу поиска, но теряет все сделанные им выборы.

 if (Request.UrlReferrer != null)
        return Redirect(Request.UrlReferrer.ToString());
  

Я пытался обойти проблему, используя TempData, но я получаю «Результат запроса не может быть перечислен более одного раза».-Исключение.

 private SearchViewModel EnsureViewModel(SearchViewModel viewModel)
    {
        if (TempData["SearchModel"] != null amp;amp; viewModel.SearchResult == null)
            viewModel = TempData["SearchModel"] as SearchViewModel;

        TempData["SearchModel"] = viewModel;
        return viewModel;
    }
  

Здесь, где я показываю список своих результатов в модели, генерируется исключение:

 @Html.DisplayFor(p => Model.SearchResult)
  

Я также подумал, что может быть способ сделать это с использованием частичного представления?
Конечно, мой последний ресурс просто дублирует код, но я не в восторге от этой идеи…

Любые идеи приветствуются, спасибо =)


Редактировать Вызов контроллера выполняется с использованием формы следующим образом:

 @using (Html.BeginForm("Add", "Basket", new { id = Model.Name } ))
    {
        @Html.TextBox("amount", "1", new { name="amount", maxlength=7, @class = "txtfield number" })
        <button><img src="@Url.Content("~/Content/images/icon_basket.gif")" border="0" width="14" height="10" class="basket" /></button>
    }       
  

Комментарии:

1. Не уверен точно, в чем ваша проблема… Почему вы не можете просто настроить форму в своем представлении для публикации всех проверенных продуктов непосредственно в BasketController ?

2. У него есть кнопка «Добавить в корзину», которая добавляет товар в корзину через контроллер корзины, но пользователь должен указать на странице поиска модель представления поиска. Я надеюсь, что это немного прояснит ситуацию…

Ответ №1:

Я думаю, что перенаправление — это то, что приводит к увеличению временных данных, попробуйте заменить «Перенаправление» в коде вашего контроллера на «View» и передать ему имя представления (не весь URL).

(Примечание: если ваше действие контроллера выполняло что-либо для заполнения модели представления, вам нужно скопировать этот код и вставить его непосредственно перед вызовом представления (я извлекаю его в частный метод и вызываю его из обоих мест))

Комментарии:

1. Временные данные отлично справляются с перенаправлением, и я решил пока сделать это таким образом и записать все значения SearchModel обратно, хотя мне это и не нравится, другого способа я не нашел…

Ответ №2:

Почему бы не вызвать метод «Добавить в корзину» с помощью AJAX? Тогда пользователям не нужно покидать вашу страницу поиска, чтобы добавить товары в корзину, что сохранит их поиск.

Кроме того, когда я реализую параметры поиска, я часто передаю эти параметры в строке запроса. Они по-прежнему заполняют SearchViewModel, но их наличие в строке запроса позволяет при необходимости довольно легко передавать их между веб-запросами.

Комментарии:

1. Проблема в том, что сайт должен работать с отключенным javascript, поэтому я стараюсь избегать AJAX. Также в поиске есть список примерно из 20 категорий и других дополнительных значений, и я не хочу сохранять их в строке запроса, если в этом нет необходимости.

2. Строка запроса отлично работает, когда вам нужно добавить только один элемент, но как бы вы разместили содержимое текстового поля (количество элементов, которые нужно упорядочить)? Легко с AJAX, но с отключенным JavaScript?

3. Вы можете установить для атрибута метода формы значение «get», чтобы включить все поля формы в строку запроса.

Ответ №3:

Если вы не можете использовать AJAX, есть другой вариант:

  1. Сохраните все элементы корзины в сеансе (очевидно).
  2. При отображении страницы результатов поиска для каждого элемента проверьте, находится ли он уже в корзине. Если это так, покажите, что это проверено.
  3. Когда пользователь нажимает «Добавить в корзину», очистите свою корзину и повторно заполните ее, используя это последнее сообщение.

Конечно, я не уверен, используете ли вы разбивку на страницы. Если да, то это решение, вероятно, не будет работать…