ASP.NET MVC: рекомендации по сохранению состояния сеанса в приложении, подобном мастеру - PullRequest
5 голосов
/ 06 августа 2009

Допустим, у меня есть веб-приложение, реализованное как набор страниц мастера для редактирования сложного объекта. До тех пор, пока пользователь не нажмет кнопку «Готово», объект не будет сохранен в серверной системе (требование), поэтому в то же время мне приходится хранить всю информацию об объекте в каком-то состоянии сеанса .

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

По совпадению, мастер позволяет пользователю свободно переходить с одной страницы мастера на любую другую (используя ссылки на вкладки в верхней части формы), так что это не простая вещь "следующий, следующий ... закончить".

Дополнительное ограничение: веб-приложение работает в веб-ферме, и клиент устал от использования состояния сеанса на стороне сервера. В лучшем случае они хотят, чтобы размер состояния сеанса был минимальным (у них были проблемы с этим в прошлом).

Итак, в основном здесь есть две проблемы:

  1. Как / где хранить данные, введенные пользователем в мастере?
  2. Кэшировать ли элементы комбинированного списка / списка, полученные от сервера, и если да, то где?

Варианты, которые я рассматриваю:

  1. Хранение объекта в WebForms-подобных ViewState (путем сериализации его в HTML-страницу). Это также будет включать элементы комбинированного списка. Очевидно, что проблема может быть связана с тем, что HTML-страницы становятся очень большими, и поэтому веб-приложение будет работать медленно.

  2. Сохранение в состоянии сеанса на стороне сервера , независимо от пожеланий клиента и без знания того, как будет влиять производительность, до тех пор, пока она не будет протестирована в реальной веб-ферме (в конце проекта) .

Я не могу выбрать между ними. Или есть другая альтернатива?

Ответы [ 8 ]

5 голосов
/ 06 августа 2009

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

3 голосов
/ 06 августа 2009

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

2 голосов
/ 06 августа 2009

Как сказала Дейзи, его не нужно кэшировать. Вы также можете использовать скрытые поля формы. Поскольку они могут отображаться на один и тот же объект при каждом действии контроллера, вы можете постепенно создавать этот объект на последующих страницах.

//Here's a class we're going to use
public class Person
{
  public int Age {get;set;}
  public string Name {get;set;}

  public Person()
  {
  }
}

//Here's the controller
public Controller PersonCreator
{
  public ActionResult CreatePerson()
  {
    //Posting from this page will go to SetPersonAge, as the name will be set in here.
    return View();
  }

  public ActionResult SetPersonAge(Person person)
  {
    //This should now have the name and age of the person
    return View(person);
  }
}

//Here is your SetPersonAge, which contains the name in the model already:
<%= Html.Hidden("Name", Model.Name) %>
<%Html.TextBox("Age") %>

И это почти все.

1 голос
/ 25 сентября 2011

Если вы не можете использовать ajax (для проверки и раскрытия и возможности конвертировать мастера на страницу с вкладками) и не можете использовать html5 (для кэширования выпадающего списка и сохранения состояния формы в локальном хранилище), то я думаю, что вы довольно недоступны "лучший практики ", и вы должны прибегнуть к плохому (или хуже).

Поскольку MVC является противником веб-форм в отношении использования сеансов, может быть, вы можете использовать обходной путь? Например, помимо сохранения всех этих значений в некоторых временных записях базы данных, которые необходимо очистить позже, вы можете установить расширение AppFabric для Windows Server и использовать его для хранения элементов раскрывающегося списка (а область действия может быть для всех пользователи, поэтому, если больше пользователей используют систему одновременно, вам нужно всего лишь один вызов веб-службы для обновления кэша), а также для временного хранения ваших объектов между этапами. Вы можете настроить временные объекты в AppFabric на автоматическое истечение срока действия, чтобы очистка не требовалась. Это также может помочь ускорить работу других частей вашей системы, если вы активно вызываете другую систему через веб-службы.

1 голос
/ 01 сентября 2011

Существует большое сопротивление в сообществе MVC против использования сессий. Проблемы в том, что многие из нас, разработчиков, создают системы входа в систему, такие как веб-сайт банка. Можно спорить о скрытых полях, и это работает в некоторых ситуациях, но когда нам нужно определить время пользователя для обеспечения безопасности и соответствия, у вас есть несколько вариантов. Печенье не надежно. Использование таймеров Javascript ненадежно и не соответствует требованиям 508, поскольку целью должно быть постепенное ухудшение качества. Таким образом, для входа в систему сеанс является хорошим вариантом. Если вы записываете время в браузер клиента, в базу данных сервера или файловую систему сервера, вам все равно придется управлять временем для каждого пользователя.

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

1 голос
/ 06 августа 2009

Я могу предложить еще несколько вариантов

  1. Наличие всего мастера в виде одной страницы с вкладками, показывающими и скрывающими контент через JavaScript на стороне клиента. Это может привести к тому, что начальная страница будет загружаться медленнее.

  2. Кэширование данных на сервере с использованием блока приложения кеширования (или чего-то подобного). Это позволит всем пользователям совместно использовать один экземпляр этих данных вместо дублирования во всех сеансах. Теперь, когда данные меньше, вы можете убедить клиента разрешить хранение в сеансе.

0 голосов
/ 19 июня 2013

Ответ на этот вопрос можно найти в ASP.NET MVC Стива Сандерсона 2/3 , и для него требуется ссылка на сборку MVC Futures. Эта ссылка на Google Книги - именно то, что он делает.

По сути, вы сериализуете данные мастера в View. Отображается скрытое поле, хранящее всю полученную информацию.

Ваш контроллер может решить, что делать, используя OnActionExecuting и OnResultExecuted (для обслуживания перенаправлений), чтобы передать его на следующий экран.

Прочитайте - он объясняет это гораздо тщательнее, чем я.

0 голосов
/ 08 августа 2009

Я имел дело с той же проблемой, и, хотя мои требования немного проще (сохранение состояния для нескольких строк), моё решение может работать для вас. Мне также было бы интересно услышать мнение других об этом подходе.

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

//Here's the controller
public Controller PersonCreator  
{  
    public ActionResult CreatePerson()  
    {    
        //get the age out of the session
        int age = (int)(Session["age"]);
        //do something with it...
        return View();  
    }  
    public ActionResult SetPersonAge(Person person)  
    {  
        //put the age in the session
        Session.Add("age", person.Age);
        return View(person);  
    }
}

Что мне нравится в этом, так это то, что мне не нужно размещать кучу скрытых параметров на страницах просмотра.

...