Как интегрировать состояние сеанса в приложение ASP.NET MVC? - PullRequest
7 голосов
/ 29 января 2009

Я ищу мысли о том, как использовать Session в приложении ASP.NET MVC? Особенно при использовании мастер-страниц и попыток просто получить данные на мастер-страницу, не обходя контроллер. Этот вопрос начался с того, что я задал много небольших вопросов, но затем мне удалось превратить его в решение, которое я пока не реализовал, но которое несколько работоспособно. Буду признателен за любые отзывы.


Мое предлагаемое решение, также называемое «что я собираюсь реализовать, если кто-то не скажет« Стоп »!»

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

Мое лучшее решение следующее - показано здесь для «страницы продуктов»:

Предположение : В какой-то момент я уже застрял в сеансе с определенными данными - например, возможно, partnerId, который поступил через страницу шлюза, или свойство currentLoggedInUserEmail или полностью удаленный объект.

У меня есть класс ModelBase, от которого наследуется каждая модель, например ProductModel

У меня есть класс MySiteControllerBase (унаследованный от Controller), который имеет подкласс ProductController.

В моем методе действия в ProductController я создаю модель для вида продукта с помощью 'new ProductModel()'. Этот класс модели сам ничего не знает о сеансе или о том, как заполнять ModelBase. По сути, он даже не знает о ModelBase - он просто наследуется от него. Мой цепочечный конструктор ничего не делает (потому что я не хочу его передавать Session).

Я переопределяю View(...) в MySiteControllerBase для всех перегрузок, которые принимают параметр модели. Я проверяю, имеет ли этот параметр тип ModelBase, и если это так, я заполняю свойства, такие как partnerid и currentLoggedInuserEmail. К счастью, потому что я нахожусь в классе, который наследует от Controller, у меня есть прямой доступ к Session, поэтому я могу вытащить их прямо оттуда.

Этот метод означает, что свойства ModelBase автоматически заполняются только мной, делая 'return View(model)'. Однако существует очевидная проблема, если модели для ProductModel требуется доступ ко всему, что определено в ModelBase. Он станет нулевым, потому что он еще не заполнен.

Эту проблему можно решить, передав Session в new ProductModel(session), который, в свою очередь, передаст ее по цепочке конструктора в new ModelBase(session). Мне действительно не нравится это решение, потому что мне нравится думать о модели как о довольно глупой структуре данных, которая вообще не должна знать ни о каких внешних конструкциях данных. Другое решение может заключаться в том, чтобы просто включить его, и если я когда-нибудь обнаружу, что ProductController нужно потреблять что-то определенное в ModelBase, я просто создаю метод MySiteControllerBase.UpdateModelBase(productModel, session), чтобы явно заполнить его внутри ProductController. Я надеюсь, это ясно!

Другие вопросы, которые приходят на ум:

  • А как насчет юнит-тестирования? Есть ли какая-то абстракция вокруг состояния сеанса в MVC или я должен создать свой собственный? Я выполнил поиск по исходному коду для 'session', и ничего не вышло!
  • Как отслеживание сеансов работает с / REST / FUL / URLS в MVC? Есть ли какие-либо проблемы с cookie-файлами, о которых мне нужно знать?
  • Должен ли я думать о сессии иначе, чем у меня традиционно?

Ответы [ 2 ]

1 голос
/ 29 января 2009

Хотя в принципе нет ничего плохого в использовании Session в приложениях ASP.NET MVC (ну, по крайней мере, в этом нет ничего хуже, чем в других приложениях ASP.NET ...), но я склонен считать, что в крайнем случае, когда другие вещи не работают.

Хотя ваш вопрос, как правило, очень хорошо написан, вы не вдаваетесь в подробности того, что вы предлагаете хранить в Session. Два примера, которые я нашел в вашем вопросе:

  • Текущий пользователь электронной почты
  • Partnerid

Адрес электронной почты пользователя уже доступен при проверке подлинности с помощью форм, если вы его используете, и может быть добавлен к другим поставщикам членства ASP.NET, которые его еще не поддерживают. Непонятно, что такое partnerid на самом деле, но я скептически отношусь к тому, что Session является единственным возможным местом для его хранения.

С другой стороны, вполне возможно, что вам нужно хранить вещи, о которых вы нам не рассказали, которые действительно поместились бы в сессии.

Поэтому, прежде чем идти слишком далеко по этому пути, убедитесь, что другие решения еще не доступны для данных, которые нужно хранить.

1 голос
/ 29 января 2009

Что касается модульного тестирования, вам потребуется поддельный объект HttpContext (расширение от HttpContextBase) и поддельный объект сеанса (расширение от SessionStateBase). Или вы можете делать то, что мы делаем, и использовать Phil Haacks HttpSimulator . Не идеальное решение, но есть так много тесно связанных между собой объектов, которые соединяются вместе, когда вы делаете что-то с asp, что вы никогда не найдете действительно ничего изящного. Мы обнаружили, что продолжали сталкиваться с ним настолько, что стоило того, чтобы взять эти классы и вставить их в вспомогательную библиотеку.

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

В общем, будьте очень скудны с тем, что вы держите в сессии. Но это касается и веб-форм.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...