сжатие и данные в памяти
Прежде всего, нам нужен способ для сжатия и распаковки массива байт в памяти. Я собрал этот простой статический класс, который предоставляет два метода: «Сжать» и «Разложить».Два доступных класса, GZipStream и DeflateStream, согласно MSDN, используют один и тот же алгоритм, поэтому не имеет значения, какой из них вы выберете.
ниже код очень прост и не нуждается в дальнейшем объяснении:
using System.IO;
using System.IO.Compression;
public static class Compressor {
public static byte[] Compress(byte[] data) {
MemoryStream output = new MemoryStream();
GZipStream gzip = new GZipStream(output,
CompressionMode.Compress, true);
gzip.Write(data, 0, data.Length);
gzip.Close();
return output.ToArray();
}
public static byte[] Decompress(byte[] data) {
MemoryStream input = new MemoryStream();
input.Write(data, 0, data.Length);
input.Position = 0;
GZipStream gzip = new GZipStream(input,
CompressionMode.Decompress, true);
MemoryStream output = new MemoryStream();
byte[] buff = new byte[64];
int read = -1;
read = gzip.Read(buff, 0, buff.Length);
while(read > 0) {
output.Write(buff, 0, read);
read = gzip.Read(buff, 0, buff.Length);
}
gzip.Close();
return output.ToArray();
}
}
Вы должны сохранить этот класс в файле .cs и поместить его в каталог App_Code вашего приложения ASP.NET , убедившись, что он содержится в правильном пользовательском пространстве имен (если вы не укажете какое-либо пространство имен, класс будет доступен во встроенном пространстве имен ASP).
Сжатие ViewState
Теперь мы можем фактически сжать ViewState страницы. Для этого нам нужно переопределить два метода LoadPageStateFromPersistenceMedium и SavePageStateToPersistenceMedium. В коде просто используется дополнительное скрытое поле __VSTATE для хранения сжатого ViewState. Как вы можете видеть, просмотрев HTML-страницу, поле __VIEWSTATE пусто, а наше поле __VSTATE содержит сжатый ViewState, закодированный в Base64. Давайте посмотрим на код.
public partial class MyPage : System.Web.UI.Page {
protected override object LoadPageStateFromPersistenceMedium() {
string viewState = Request.Form["__VSTATE"];
byte[] bytes = Convert.FromBase64String(viewState);
bytes = Compressor.Decompress(bytes);
LosFormatter formatter = new LosFormatter();
return formatter.Deserialize(Convert.ToBase64String(bytes));
}
protected override void SavePageStateToPersistenceMedium(object viewState) {
LosFormatter formatter = new LosFormatter();
StringWriter writer = new StringWriter();
formatter.Serialize(writer, viewState);
string viewStateString = writer.ToString();
byte[] bytes = Convert.FromBase64String(viewStateString);
bytes = Compressor.Compress(bytes);
ClientScript.RegisterHiddenField("__VSTATE", Convert.ToBase64String(bytes));
}
// The rest of your code here...
}
В первом методе, мы просто декодировать из Base64, распаковывать и десериализацию содержания __VSTATE, и вернуть его выполнение. Во втором методе мы выполняем противоположную операцию: сериализуем, сжимаем и кодируем в Base64. Строка Base64 затем сохраняется в скрытом поле __VSTATE. Объект LosFormatter выполняет задачи сериализации и десериализации.
Возможно, вы также захотите создать новый класс, например CompressedPage, наследующий от System.Web.UI.Page, в котором вы переопределяете эти два метода, а затем наследуете свою страницу от этого класса, например MyPage: CompressedPage , Просто помните, что .NET имеет только одно наследование, и, следуя этому пути, вы «тратите» свой единственный шанс наследования использовать сжатие ViewState. С другой стороны, переопределение двух методов в каждом классе - пустая трата времени, поэтому вы должны выбрать способ, который наилучшим образом соответствует вашим потребностям.
Выше было опубликовано Дарио Солера по кодепроекту. http://www.codeproject.com/Articles/14733/ViewState-Compression
ViewState имеет это место (и затем некоторые), но выступать не использовать его вообще слишком экстремальный ИМО. Это неоценимо для хранения ключей идентификации, которые вы не хотите хранить в скрытых полях на странице (которые может испортить гнусный пользователь). Теперь, если вы храните целые DataSet или такие в нем, то, да, вам нужно переосмыслить свой игровой план. – Jagd
AFAIK ... многие мои клиенты подходят ко мне для «нескольких улучшений и улучшения производительности». В этом случае я не могу пойти на изменение логики приложения для управления сеансом, закодированной другим программистом. Мне нужно быстро реализовать (как его называет клиент), чтобы улучшить скорость приложения. –