Предисловие
Если вы немного разбираетесь в ViewState, вы знаете, что ViewState на страницах Asp.net обычно хранится в скрытом поле страницы:
<input type="hidden" name="__VIEWSTATE" id="__VIEWSTATE" value="Куча беспорядочных вещей">
Когда мы просматриваем исходный файл страницы, мы видим много беспорядочных вещей (особенно, когда на странице есть DataGrid с большим объемом данных или GridView в ASP.NET 2.0). время, это ViewState.
Базовые знания
Поскольку в механизме постоянного хранения ViewState в ASP.NET 2.0 есть некоторые новые изменения, я кратко представлю соответствующие вещи.
В ASP.NET 1.1 предусмотрен только механизм сохранения скрытого домена страницы, поэтому в некоторых случаях от использования ViewState придется отказаться. Представьте себе, если в вашем DataGrid десятки тысяч записей (не думайте). это ненормально) Нет необходимости (кто-то сталкивался с этим) Если ViewState включен, вы уверены, что ваш IIS-сервер его выдержит и выдержит ли сеть? Конечно, вы можете изменить свой механизм хранения, переопределив метод Page.SavePageStateToPersistenceMedium(), но не забудьте переопределить Page.LoadPageStateFromPersistenceMedium(), они представляют собой пару.
Механизм сохранения состояния представления по умолчанию в ASP.NET 2.0 по-прежнему сохраняет информацию о состоянии в виде строки в кодировке Base64 в скрытом элементе HTML на странице (элементе с атрибутом type, имеющим значение «скрытый»). Страницы ASP.NET используют объект HiddenFieldPageStatePersister для выполнения этой работы и экземпляр IStateFormatter для сериализации и десериализации информации о состоянии объекта. Или, для мобильных клиентов с ограниченной пропускной способностью и ресурсами, вы также можете использовать класс SessionPageStatePersister для хранения состояния просмотра страницы в объекте Session на сервере. Фактически, существует только еще один механизм сохранения сеанса. состояние страницы в сеансе, а не на странице, что позволяет экономить полосу пропускания.
Но если вы хотите глубже понять механизм сохранения состояния ViewState, вам следует знать об абстрактном классе PageStatePersister. Чтобы сохранить состояние представления на клиенте, который не может поддерживать существующий механизм сохранения состояния просмотра, вы можете расширить класс PageStatePersister и ввести свой. собственные методы сохранения состояния представления, и вы можете использовать адаптеры страниц для настройки приложений ASP.NET на использование различных механизмов сохранения состояния представления в зависимости от типа клиента, которому обслуживается страница. Классы, производные от класса PageStatePersister, должны переопределить абстрактный метод Save для хранения состояния представления и состояния управления в постоянном носителе, а также переопределить метод Load для извлечения информации о состоянии. Если вам нужно сериализовать состояние представления и состояние управления в строки, вы можете использовать объект IStateFormatter, доступ к которому осуществляется через свойство StateFormatter. Он эффективно сериализует и десериализует информацию о состоянии объекта в строки в кодировке Base64. Вы также можете переопределить свойство StateFormatter, чтобы предоставить свой собственный механизм сериализации состояния объекта. Как это сделать, вы поймете, посмотрев.
Скрытое поле
механизма сохранения ViewState
не будет введено. Это значение по умолчанию. Как сказано в предисловии.
Сеансу
необходимо только переопределить свойство PageStatePersister в ASP.NET2.0.
защищенное переопределение PageStatePersister PageStatePersister
{
получать
{
вернуть новый SessionPageStatePersister(Page);
}
}
Если вам нужно переопределить эти два метода LoadPageStateFromPersistenceMedium в ASP.NET1.1:
защищенный объект переопределения LoadPageStateFromPersistenceMedium().
{
вернуть сеанс["ViewState"];
}
защищенное переопределение void SavePageStateToPersistenceMedium (объект viewState)
{
Session["ViewState"] = viewState;
RegisterHiddenField("__VIEWSTATE", "");
}
База данных (мой пример — SQL Server2000)
находится в формате ASP1.1. Обратите внимание на фиолетовую строку ниже. Я не знаю, в чем ее смысл, на несколько дней я впал в депрессию. . Следующий код просто скопирован из моего исходного кода. Вам вообще не обязательно писать его так, за исключением тех случаев, когда это необходимо.
защищенное переопределение void SavePageStateToPersistenceMedium (состояние объекта)
{
строка viewStateID = "VIEWSTATE#" + Session.SessionID.ToString() + "#" + DateTime.Now.Ticks.ToString();
ClientScript.RegisterHiddenField("__VIEWSTATE_KEY", viewStateID);
ClientScript.RegisterHiddenField("__VIEWSTATE","");//Обратите внимание,
попробуйте
{
если (losFormatter == ноль)
{
losFormatter = новый LosFormatter();
}
StringWriter sw = новый StringWriter();
losFormatter.Serialize(sw, состояние);
Common.ViewStateData vsd = новый ViewStateData();
vsd.ViewStateID = viewStateID;
vsd.ViewState = sw.ToString();
да = новый DataAccess();
строковая ошибка = da.SaveViewState(vsd);
Ответ.Запись(ошибка);
}
поймать (Исключение ex)
{
Response.Write(ex.Message);
}
}
защищенный объект переопределения LoadPageStateFromPersistenceMedium()
{
строка viewState = string.Empty;
пытаться
{
если (losFormatter == ноль)
{
losFormatter = новый LosFormatter();
}
строка stateID = Page.Request["__VIEWSTATE_KEY"].ToString();
да = новый DataAccess();
viewState = da.LoadViewState(stateID);
}
ловить
{}
return losFormatter.Deserialize(viewState);
}
Эта строка кода в целом подходит для ASP2.0. Почему она базовая? Потому что это строка выше ClientScript.RegisterHiddenField("__VIEWSTATE","")
;
.net1.1 Это возможно. Я также сослался на код других людей и добавил эту строку. После добавления этой строки настранице
появляется только дополнительный <input type="hidden" name="__VIEWSTATE" value="" />.
.
В исходном файле страницы после запуска есть две такие вещи. Можно удалить эту строку, поэтому я не понимаю, для чего используется это утверждение. Пожалуйста, скажите мне четко. Но это не работает в Asp.net2.0. Возникает следующая ошибка:
Информация о состоянии для этой страницы недействительна и может быть повреждена.
В любом случае, в тот момент я был в замешательстве и никогда раньше не сталкивался с такой ошибкой. и я ничего не могу найти в Google, да, я не знаю, неверно ли это предложение. Я уже два дня в депрессии, и проблема не может быть решена. Я, естественно, глуп. сохранив состояние просмотра в базу данных и прочитав его из базы данных, я не смог найти ошибку, поэтому снова и снова думал о коде, но меня немного смущала эта строка. Почему страница должна регистрировать скрытую информацию. поле «__VIEWSTATE», поэтому я закомментировал эту строку, и она действительно сработала. Так что я до сих пор не понимаю, для чего нужна эта строка.
Конечно, мы также можем завершить вышеуказанные функции, написав новый подкласс PageStatePersister, который является новым в ASP.NET2.0:
пространство имен PageAdapter.
{
использование системы;
использование System.IO;
использование System.Security.Permissions;
использование System.Web;
использование System.Web.UI
[AspNetHostingPermission(SecurityAction.Demand, Level = AspNetHostingPermissionLevel.Minimal)]
общедоступный класс DatabasePageStatePersister: PageStatePersister;
{
общедоступная база данныхPageStatePersister (страница страницы): база (страница)
{}
//
// Загружаем ViewState и ControlState.
//
публичное переопределение void Load()
{
строка ViewState;
Форматер IStateFormatter = this.StateFormatter;
DataAccess da = новый DataAccess();
строка stateID = base.Page.Request["__VIEWSTATE_KEY"].ToString();
viewState = da.LoadViewState(stateID);
Пара statePair = (Пара)formatter.Deserialize(viewState);
ViewState = statePair.First;
ControlState = StatePair.Second;
}
//
// Сохраняем любые ViewState и ControlState.
//
публичное переопределение void Save()
{
если (ViewState != null || ControlState != null)
{
если (Page.Session!= ноль)
{
строка viewStateID = "VIEWSTATE#" + base.Page.Session.SessionID.ToString() + "#" + DateTime.Now.Ticks.ToString();
base.Page.ClientScript.RegisterHiddenField("__VIEWSTATE_KEY", viewStateID);
Пара statePair = новая пара (ViewState, ControlState);
Форматер IStateFormatter = this.StateFormatter;
// Сериализуем объект statePair в строку
string serializedState = formatter.Serialize(statePair);
ViewStateData vsd = новый ViewStateData ();
vsd.ViewStateID = viewStateID;
vsd.ViewState = сериализованноеСостояние;
DataAccess da = новый DataAccess();
строковая ошибка = da.SaveViewState(vsd);
}
еще
throw new InvalidOperationException("Для StreamPageStatePersister необходим сеанс.");
}
}
}
}
Затем вы можете переопределить свойство PageStatePersister:
protected override PageStatePersister PageStatePersister
{
получать
{
вернуть новый DatabasePageStatePersister(Page);
}
файл
мало чем отличается от базы данных, я говорю только об ASP.NET2.0. В ASP.NET1.1 должно быть аналогично, но код для отладки я не писал:
метод до сих пор использую. написания нового подкласса PageStatePersister:
пространства имен StreamPageAdapter.
{
использование системы;
использование System.IO;
использование System.Security.Permissions;
использование System.Web;
используя System.Web.UI
//
// StreamPageStatePersister — это пример состояния просмотра
// механизм сохранения, который сохраняет просмотр и управление
// состояние на веб-сервере.
//
[AspNetHostingPermission(SecurityAction.Demand, Level = AspNetHostingPermissionLevel.Minimal)]
общедоступный класс StreamPageStatePersister : PageStatePersister
{
public StreamPageStatePersister (страница страницы): база (страница)
{}
//
// Загружаем ViewState и ControlState.
//
публичное переопределение void Load()
{
StateStream потока = GetSecureStream();
// Читаем строку состояния, используя StateFormatter.
Читатель StreamReader = новый StreamReader (stateStream);
Форматер IStateFormatter = this.StateFormatter;
строка fileContents = Reader.ReadToEnd();
// Десериализация возвращает объект Pair, сериализованный в
// метод Сохранить.
Пара statePair = (Пара)formatter.Deserialize(fileContents);
ViewState = statePair.First;
ControlState = StatePair.Second;
читатель.Закрыть();
StateStream.Close();
}
//
// Сохраняем любые ViewState и ControlState.
//
публичное переопределение void Save()
{
если (ViewState != null || ControlState != null)
{
если (Page.Session!= ноль)
{
StateStream потока = GetSecureStream();
Писатель StreamWriter = новый StreamWriter (stateStream);
Форматер IStateFormatter = this.StateFormatter;
Pair statePair = new Pair(ViewState, ControlState);
// Сериализуем объект statePair в строку.
строка SerializedState = форматтер.Serialize(statePair);
писатель.Write(serializedState);
писатель.Закрыть();
StateStream.Close();
}
еще
throw new InvalidOperationException("Для StreamPageStatePersister необходим сеанс.");
}
}
// Возвращаем безопасный поток для вашей среды
GetSecureStream().
{
строковый путь = @"d:a.txt";
FileStream fs = новый FileStream (путь, FileMode.Open, FileAccess.ReadWrite);
вернуть фс;
}
}
}
Просто переопределите свойство PageStatePersister:
protected переопределите PageStatePersister PageStatePersister
{
получать
{
вернуть новый StreamPageStatePersister (Страница})
;
Из приведенного выше краткого введения у нас должно быть некоторое понимание, но нам нужно понять следующее: в ASP.NET1.1 мы можем выполнить вышеуказанные функции, только переписав age.SavePageStateToPersistenceMedium() и Page.LoadPageStateFromPersistenceMedium(), находясь в ASP; .NET1.1 В ASP.NET2.0, помимо этого, мы также дополнили это, написав новый подкласс PageStatePersister и переопределив свойство PageStatePersister. Я не нашел никакой разницы. Конечно, если вы прочитаете следующий контент. , вы поймете, что написание нового подкласса PageStatePersister имеет реальное применение.
Использование адаптера страницы
Поскольку механизм сохранения состояния связан с адаптивной отрисовкой и функциональностью на стороне клиента, MyPageAdapter предоставляется для активации DatabasePageStatePersister приложения ASP.NET. Наконец, предоставляется файл возможностей браузера (.browser), позволяющий включить MyPageAdapter для определенного класса клиентов (в данном случае веб-браузера по умолчанию).
Это содержимое можно найти в проекте PageAdapter в предоставленном мною исходном коде. Вы поймете после прочтения.
использование System.Security.Permissions;
использование System.Web;
пространства имен
System.Web.UI PageAdapter;
{
[AspNetHostingPermission(SecurityAction.Demand, Level = AspNetHostingPermissionLevel.Minimal)]
общедоступный класс MyPageAdapter: System.Web.UI.Adapters.PageAdapter
{
общедоступное переопределение PageStatePersister GetStatePersister()
{
вернуть новый PageAdapter.DatabasePageStatePersister(Page);
}
}
}
Наконец, чтобы включить адаптер MyPageAdapter, вы должны создать каталог с именем App_Browsers в корневом каталоге приложения ASP.NET и включить файл .browser, содержащий информацию о конфигурации (фактически, все они добавляются при его добавлении). в проект Файл .browser будет автоматически завершен для вас с помощью vs2005. Элемент <refID в файле конфигурации указывает, что конфигурация переопределяет значение, указанное браузером по умолчанию в файле конфигурации Default.browser. В этом примере используется MyPageAdapter для ASP. Веб-страницы .NET (но обычно
адаптеры
не используются).
<refID браузера="По умолчанию" >
<Адаптеры управления>
<адаптер
controlType="System.Web.UI.Page"
адаптерТип="PageAdapter.MyPageAdapter" />
</controlAdapters>
</браузер>
</браузеры>
Это можно увидеть в проекте TestPageAdapter в исходном коде. Этот проект используется для демонстрации адаптера страницы.
Вывод
относительно простой и может быть не очень понятным. Что касается преимуществ и недостатков различных механизмов сохранения, я его специально не проверял, а последний пункт «Использовать адаптер страницы» не является механизмом сохранения, а использует адаптер. , поэтому мы не будем переопределять
атрибут PageStatePersister. Мне кажется, это не очень полезно, потому что мы можем поместить действие переопределения PageStatePersister в базовый класс страницы, и все остальные страницы смогут наследовать этот базовый класс. как это в моем коде. Использовать этот адаптер страницы проблематично. Конечно, я мало что знаю об адаптере страницы.
Кроме того, краткое пояснение моего исходного кода:
1. Проект PageAdapter
DatabasePageStatePersister.cs: подкласс класса PageStatePersister MyPageAdapter.cs: адаптер страницы DataAccess.cs и доступ к базе данных ViewSate.cs, принадлежащий вспомогательному классу.
2. Проект StreamPageAdapter
аналогичен приведенному выше, поэтому не буду вдаваться в подробности.
3. Проект SaveStateToDatabase
StateInHiddenField.aspx: Протестируйте механизм хранения по умолчанию, то есть при просмотре можно увидеть много всякой ерунды. исходный файл страницы.
StateInSession.aspx: механизм хранения — сеанс.
StateInDatabase.aspx: база данных механизма хранения — это тип метода перезаписи. Его можно использовать в asp.net1.1 и 2.0.
StateInDatabase2.aspx: напишите новый подкласс PageStatePersister и переопределите свойство PageStatePersister.
StateInFile.aspx: сохраните ViewState в папке на сервере.
4. Проект TestPageAdater.
Используется для тестирования и адаптеров.