Лучшие практики для передачи данных между страницами

Проблема

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

Сама потеря сессии является проблемой, хотя она главным образом обрабатывается путем реализации Сервера Состояния сеанса (или при помощи SQL Server). Что еще более важно, это хитро, чтобы заставить кнопку "Назад" работать правильно, и это - также дополнительная работа для создания ситуации, где пользователь может, скажем, открыть тот же экран на трех вкладках для работы над различными записями.

И это - просто верхушка айсберга.

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

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

Также было бы хорошо, если бы конечное решение не привело к горам шаблонного кода инфраструктуры.

Предлагаемые решения

Сессия

Как упомянуто выше, склонение в большой степени на Сессии походит на хорошую идею, но это повреждает кнопку "Назад" и вызывает некоторые другие проблемы.

Могут быть способы обойти все проблемы, но это походит на большую дополнительную работу.

Одной вещью это очень хорошо об использовании сессии, является то, что вмешательство является просто не проблемой. По сравнению с передачей всего через незашифрованный QueryString Вы заканчиваете тем, что написали намного меньше защитного кода.

Регистрация перекрестной страницы

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

Это кажется ограниченным другими способами также. Возможно, я хочу добраться до страницы по ссылке, например.

QueryString

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

На 4 парнях из Роллы существует статья об этом.

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

Другие опции

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

В закрытии...

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

Заранее спасибо!

Обновление: На всякий случай я не достаточно ясен 'передающими данными между страницами', я говорю о, например, передавая ключ CustomerID от страницы CustomerSearch.aspx до Customers.aspx, где Клиент будет открыт, и редактирование может произойти.

64
задан Carlos Muñoz 12 April 2016 в 16:36
поделиться

4 ответа

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

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

3
ответ дан 24 November 2019 в 16:00
поделиться

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

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

При переработке я сделал Id сотрудника и Id запроса доступными через базовый URL "ViewEmployee.aspx?Id=XXX" и "ViewRequest.aspx?Id=XXX". Приложение было настроено на A) отфильтровывание плохих идентификаторов и B) аутентификацию и авторизацию пользователя перед тем, как допустить его на эти страницы. Это позволяло пользователям приложения в основном отправлять простые электронные письма аудиторам с URL-адресом в письме. Когда они очень торопились, у них было время массовой обработки, они могли просто щелкнуть по списку URL-адресов и выполнить соответствующую обработку".

Другие данные, связанные с сессиями, такие как даты модификации и поддержание "состояния" взаимодействия пользователя с приложением, немного сложнее, но, надеюсь, это послужит для вас отправной точкой.

2
ответ дан 24 November 2019 в 16:00
поделиться

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

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

  • Строка запроса - Строки запроса хороши для передачи указателей на данные (например, значения первичного ключа) или значений состояния.Строки запроса сами по себе не должны считаться безопасными, даже если они зашифрованы из-за воспроизведения. Кроме того, в некоторых браузерах есть ограничение на длину URL-адреса. Однако строки запроса имеют некоторые преимущества, такие как то, что их можно добавлять в закладки и отправлять по электронной почте людям, и они по своей природе не имеют состояния, если не используются с чем-либо еще.

  • Файлы cookie - файлы cookie удобны для хранения очень небольших объемов информации о конкретном пользователе. Проблема в том, что файлы cookie также имеют ограничение по размеру, после которого они просто усекают данные, поэтому вы должны быть осторожны с помещением пользовательских данных в файл cookie. Кроме того, пользователи могут уничтожить файлы cookie или прекратить их использование (хотя это также предотвратит использование стандартного сеанса). Подобно строкам запроса, файлы cookie, IMO, лучше подходят для указателей на данные, чем для самих данных, если данные не крошечные.

  • Данные формы - данные формы могут занимать довольно много информации, однако за счет времени публикации и, в некоторых случаях, времени перезагрузки. ViewState в ASP.NET использует скрытые переменные формы для хранения информации. Передача данных между страницами с использованием чего-то вроде ViewState имеет то преимущество, что лучше работает с кнопкой «Назад», но может легко создавать огромные страницы, которые замедляют работу пользователя. В общем, модель ASP.NET не работает с межстраничной публикацией (хотя это возможно), но вместо этого работает с сообщениями, возвращающимися на ту же страницу и оттуда переходящими на следующую страницу.

  • Сеанс - Сеанс полезен для получения информации, относящейся к процессу, с которым работает пользователь, или для общих настроек.Вы можете хранить довольно много информации в сеансе за счет памяти сервера или времени загрузки из баз данных. Концептуально сеанс работает, загружая для пользователя весь пакет данных сразу либо из памяти, либо с сервера состояний. Это означает, что если у вас очень большой набор данных, вы, вероятно, не захотите помещать его в сеанс. Сеанс может создать некоторые проблемы с кнопкой «Назад», которые необходимо сопоставить с тем, что пользователь на самом деле пытается выполнить. В общем, вы обнаружите, что кнопка «Назад» может быть отравой для веб-разработчика.

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

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

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

41
ответ дан 24 November 2019 в 16:00
поделиться

Хорошо, я хочу предварить свой ответ этим; У Томаса явно есть наиболее точный и исчерпывающий ответ для людей, начинающих с нуля. Этот ответ совсем не в том же духе. Мой ответ исходит с точки зрения «бизнес-разработчика». Как мы все слишком хорошо знаем; иногда просто нереально тратить деньги на то, чтобы переписать то, что уже существует и «работает» ... по крайней мере, не все в одном кадре. Иногда лучше реализовать решение, которое позволит вам со временем перейти на лучшую альтернативу.

Единственное, чего, я бы сказал, не хватает Томасу, - это; состояние javascript на стороне клиента. Там, где я работаю, мы обнаружили, что клиенты все больше и больше ждут от приложений типа "Web 2.0". Мы также обнаружили, что такие приложения обычно приводят к гораздо большему удовлетворению запросов пользователей. После небольшой практики и помощи некоторых действительно отличных библиотек javascript, таких как jQuery (мы даже начали использовать GWT и обнаружили, что это УДИВИТЕЛЬНО), взаимодействие с REST-сервисами на основе JSON, реализованными в WCF, может быть тривиальным. Этот подход также предоставляет очень хороший способ начать движение к архитектуре на основе SOA и четкому разделению пользовательского интерфейса и бизнес-логики.

Но я отвлекся.

Мне кажется, что у вас уже есть приложение, и вы уже расширили границы встроенного в ASP.NET управления состоянием сеанса. Итак ... вот мое предложение (при условии, что вы уже пробовали внепроцессное управление сеансами ASP.NET, которое масштабируется значительно лучше, чем внутрипроцессное / внутреннее управление сеансами, и похоже, что вы это сделали, потому что вы упомянули Это); NCache.

NCache предоставляет вам «прямую» замену опциям управления сеансами ASP.NET. Его очень легко реализовать, и он может более чем «подправить» ваше приложение, чтобы вы могли его освоить - без каких-либо значительных вложений в немедленный рефакторинг существующей кодовой базы.

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

Только мои мысли.

9
ответ дан 24 November 2019 в 16:00
поделиться
Другие вопросы по тегам:

Похожие вопросы: