ASP.NET MVC - есть ли способ имитировать ViewState?

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

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

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

Кто-нибудь знает как это сделать?? Кто-нибудь знает, как временно сохранить эти данные без использования cookie или сеанса ??

Спасибо!!


person André Miranda    schedule 21.03.2009    source источник
comment
Почему ограничение на неиспользование Сессии? Я использую сеанс для хранения результатов шагов многошагового мастера.   -  person tvanfosson    schedule 21.03.2009


Ответы (4)


Скрытые поля ввода не помогут?

<%= Html.Hidden(...) %>

Обновление (сериализация объекта в base64):

var formatter = new BinaryFormatter();
var stream = new MemoryStream();
formatter.Serialize(stream, myObject); // myObject should be serializable.
string result = Convert.ToBase64String(stream.ToArray());

Когда вы захотите вернуть его:

var formatter = new BinaryFormatter();
var stream = new MemoryStream(Convert.FromBase64String(hiddenFieldValue));
var myObject = (MyObjectType)formatter.Deserialize(stream);

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

Дополнительное примечание: ASP.NET использует LosFormatter вместо BinaryFormatter для сериализации ViewState, поскольку это более эффективная или основанная на ASCII сериализация. Возможно, вы тоже захотите это рассмотреть.

person mmx    schedule 21.03.2009
comment
Я использую скрытые поля для некоторых вещей ... но как я могу сохранить список объектов в скрытом поле ?? - person André Miranda; 21.03.2009
comment
Двоичная сериализация объекта и преобразование байта [] в строку base64. - person mmx; 21.03.2009
comment
Мехрдад, я пытался это сделать, но выдал ошибку, говоря, что моя сущность не помечена как сериализуемая. Я использую LINQ to SQL. - person André Miranda; 21.03.2009
comment
Кстати, я предлагаю вам не сериализовать класс сущности. Создайте отдельный класс с соответствующими полями, которые вам нужны, и сделайте его сериализуемым. На последнем этапе создайте объект на основе данных в этом классе и отправьте его в БД. - person mmx; 21.03.2009
comment
В файле кода, связанном с DBML, вы можете создать частичный класс, соответствующий вашей сущности, и пометить его как сериализуемый. Однако, как я предлагал в своем последнем комментарии, лучше создать новый класс на основе данных, которые вы хотите сохранить, и вместо этого сделать этот [Serializable]. - person mmx; 21.03.2009
comment
Это сбивает с толку хехехе! Например, у меня есть этот объект SchedulePeriod и поля hourInitial, hourEnd и будний день ... - person André Miranda; 21.03.2009
comment
Моим последним комментарием был ваш ответ о создании еще одного класса - person André Miranda; 21.03.2009
comment
Создайте свой собственный класс с этими полями (забудьте о классах DBML). Отметьте этот класс как сериализуемый. Когда вы будете готовы сохранить его в БД, заполните класс DBML данными из ваших собственных. понятно? - person mmx; 21.03.2009
comment
И этот «строковый результат» я отправлю в свое скрытое поле, верно? - person André Miranda; 21.03.2009
comment
Cai использует это для сохранения списка объектов, например IList ‹SchedulePeriod› ?? - person André Miranda; 21.03.2009
comment
Это работает для всех сериализуемых объектов. Список ‹T› сериализуем, если сериализуем сам T. Так что да, если вы можете хранить SchedulePeriod, вы также можете хранить List ‹SchedulePeriod›. Кстати, это зависит от фактического типа IList. Об интерфейсе IList ‹T› в целом ничего нельзя сказать. Список ‹T› хоть и работает. - person mmx; 21.03.2009
comment
Например, Мехрдад. Пользователь выберет начальный час, последний час и день недели и нажмет «сохранить». Это вызовет метод, который будет сериализовать мой новый класс, который я создал, и передать его скрытому. Однако пользователь выберет другой последний и начальный час и день недели и сохранит ... - person André Miranda; 21.03.2009
comment
и это также сериализует мой новый класс и передаст его в скрытое поле, но он будет использовать только последнее действие «сохранить», я прав? Первое «сохранение», сделанное пользователем, было потеряно, верно? Вот почему я спросил вас о сохранении объектов в списке. - person André Miranda; 21.03.2009
comment
До сих пор я сохранял список в сеансе, и когда пользователь выбирал другой начальный и последний час и день недели, он сохранял эти данные, и мой метод проверял, есть ли у сеанса список. Если это так, эти новые данные будут добавлены в Список. Но Сессия продолжает то, что делает. - person André Miranda; 21.03.2009
comment
Я думаю, что если сериализовать и сохранить его в скрытом, он сохранит только последнее «сохранение», потому что у меня не будет места для хранения данных, введенных ранее пользователем ... - person André Miranda; 21.03.2009
comment
Да, это сработает. Вы также можете рассмотреть приложение в стиле AJAX, которое делает все это на клиенте, а затем сразу отправляет его на сервер. - person mmx; 21.03.2009
comment
Я думаю, мне придется передать значение скрытого поля в качестве параметра моего метода, проверить, что в нем что-то есть, если это так, десериализуйте его и сохраните последние данные, введенные в этот список, снова сериализуйте его и верните обратно в мои скрытые ... - person André Miranda; 21.03.2009
comment
Да, тебе придется это сделать. Вы можете избежать обратных передач, также выполнив выбор и добавив в список с помощью javascript и отправив весь список данных на сервер. - person mmx; 21.03.2009
comment
Есть ли у этого «строкового результата» ограничение по размеру ?? - person André Miranda; 21.03.2009
comment
2 ГБ :) Предупреждение: если у вас столько данных, что вы думаете об ограничении размера, ViewState и подобные вещи, вероятно, не подходят. - person mmx; 21.03.2009
comment
ой! 2 ГБ ?? Мои данные faaar ниже этого! :-) Я протестирую и скажу, сработало ли! - person André Miranda; 21.03.2009
comment
Когда я пытаюсь десериализовать его, он выдает ошибку, говоря, что моя длина данных недействительна ... он отлично шифрует (по крайней мере, кажется), но при десериализации выдает ошибку - person André Miranda; 21.03.2009
comment
Я сдался ... я сказал, что длина данных недействительна ... неважно, я попробую это в другой раз. Но, спасибо за помощь ... :-) - person André Miranda; 21.03.2009

TempData ["MyData"], имейте в виду, что это продлится только один путь туда и обратно.

person Al Katawazi    schedule 21.03.2009

Вы можете сохранить массив javascript на клиенте ... и затем передать всю информацию, когда пользователь в конечном итоге сохранит.

Придется еще немного поработать, но, в конце концов, это окупается.

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

person juan    schedule 21.03.2009
comment
Хуан, я тоже использую jQuery в проекте. Проблема в том, что эти данные сохраняются в сеансе, и я использую jQuery Flexigrid для их отображения. Моя сессия питает Flexigrid ... - person André Miranda; 21.03.2009

Если вы просто хотите сохранить данные для этого запроса и следующего запроса, я бы рекомендовал использовать Tempdata, иначе я бы рекомендовал использовать ответ Мердада.

person Community    schedule 21.03.2009