Запись в формате MVC 3 и сохраняющиеся данные модели
Я думаю, что мне не хватает основополагающих принципов работы форм MVC. У меня есть форма поиска на моей домашней странице с пятью или шестью различными полями, которые пользователь может выполнить. Таким образом, у меня есть этот POSTing для моих результатов, просто отлично. Действие Result выглядит следующим образом:
[HttpPost]
public ActionResult Results(SearchModel model)
{
ResultsModel results = new ResultsModel();
results.ResultList = SearchManager.Search(model).ToList();
return View("Results", results);
}
Я упростил вышеупомянутый метод для этого сообщения, но идея такая же. Так что все это прекрасно работает. Моя страница результатов отображается со списком результатов, и мой пользователь находится по следующему URL-адресу:
http://www.site.com/results
Итак... теперь я хочу сделать что-то довольно распространенное. У меня есть два раскрывающихся списка на странице результатов. "Сортировать по" и "Количество результатов на страницу". Как мне это сделать и отправить полный набор данных модели обратно на контроллер, чтобы я мог запрашивать новые параметры? В действительности класс SearchModel содержит около 60 различных полей. Потенциально все эти данные могут содержаться в модели. Как вы сохраняете это на странице "post back"?
В этом же вопросе я немного озадачен тем, как делать пейджинг. Мои пейджинговые ссылки перейдут на URL-адрес, например:
http://www.site.com/results/2
Но это предполагает, что мы отвечаем на запрос GET (я не хочу 60 полей данных в querystring) и что данные модели передаются между запросами GET, о которых я знаю, не так.
Как я уже сказал, я думаю, что мне не хватает основополагающих принципов работы с MVC 3, моделями и сообщениями в форме.
Может ли кто-нибудь помочь мне указать мне в правильном направлении? Я буду рад изменить/обновить этот пост по мере необходимости, чтобы прояснить ситуацию.
РЕДАКТИРОВАТЬ. Я также хотел указать, я бы хотел избежать хранения модели представления в переменной сеанса. В конечном итоге этот сайт будет сбалансирован с нагрузкой в веб-ферме, и я действительно стараюсь избежать использования сеанса, если это возможно. Однако, если это единственная альтернатива, я настрою другого поставщика состояния сеанса, но я бы предпочел не делать этого.
Ответы
Ответ 1
Вы можете добавить текущие параметры SearchModel к значениям маршрута для вашей формы. Несколько версий BeginForm позволяют вам передать объект /RouteValuesDictionary.
@Html.BeginForm("Action", "Controller", new { SearchModel = Model }, FormMethod.Post)
Это должно пройти через текущие значения SearchModel, чтобы вы могли повторно использовать их для получения следующей страницы. Необходимо определить действие контроллера, которое будет принимать любые значения формы текущей страницы, а также SearchModel.
Я не делал этого с сообщениями о форме, но из того, что я сделал, и из того, что говорят документы, я начну. Разумеется, это также означает, что каждый номер вашей страницы "ссылки" на странице должен занимать должности. Это действительно неудобно для пользователей, если они хотят иметь возможность использовать кнопку "Назад" в браузере.
В этом контексте вы можете попытаться определить маршрут, который позволяет номер страницы отображаться как часть URL-адреса - "Action/Controller/{page}". Однако я не уверен, как это будет работать, учитывая, что форма делает сообщение.
Ответ на комментарий:
Да, вы можете использовать значения маршрута для добавления SearchModel к каждой ссылке на страницу, но, как я сказал в комментарии выше, поскольку ссылки будут делать "get", ваши пользователи будут видеть, что SearchModel сериализуется как часть ссылка.
В любом случае использование значений маршрута - это ваш ответ на возврат исходной SearchModel без использования скрытых полей, сеанса или TempData.
Ответ 2
Ваш класс SearchModel должен содержать критерии поиска и ваши результаты. Что-то вроде ниже. Если вы используете PagedList для своих результатов, тогда он будет содержать текущую страницу, общие страницы, общие элементы и т.д. Вы можете ограничить количество информации на своей странице, только записывая критерии поиска, содержащие значения.
public class SearchModel
{
public string Product { get; set; }
public string Sku { get; set; }
public string Size { get; set; }
public string Manufacturer { get; set; }
// etc...
public PagedList ResultsList { get; set; }
}
[HttpPost]
public ActionResult Results(SearchModel model)
{
model.ResultList = SearchManager.Search(model).ToList();
return View(model);
}
Ответ 3
Один из вариантов, который я придумал здесь, - это реализовать распределенную систему кеширования, которая поддерживает работу как пользовательский поставщик сеансов (например, Memcached или Windows Server AppFabric), тем самым позволяя мне использовать TempData (и Session) в сбалансированная балансировка среды:
[HttpPost]
public ActionResult Results(SearchModel model)
{
ResultsModel results = new ResultsModel();
results.ResultList = SearchManager.Search(model).ToList();
TempData["SearchModel"] = model;
return View("Results", results);
}
[HttpGet]
public ActionResult Results(int? page)
{
SearchModel model = (SearchModel)TempData["SearchModel"];
ResultsModel results = new ResultsModel();
results.ResultList = SearchManager.Search(model).ToList();
TempData["SearchModel"] = model;
return View("Results", results);
}
Любые мысли об этом подходе? Кажется, что многое нужно пройти, чтобы получить параметры поиска, передаваемые между запросами. Или, может быть, я просто испортил все это, что происходит за кулисами с помощью WebForms.:)
Ответ 4
Это, по-видимому, еще один интересный вариант для Webforms spoiled guy;) Сохранение состояния модели в ASP.NET MVC с помощью Serialize HTMLHelper
Какой-то вид воплощения ViewState. Это часть MVC Futures. Не уверен, сколько времени в проекте Futures и почему он не может попасть в основную библиотеку.