Каковы последние и самые большие способы сжать содержание ASP.NET ViewState?
Что относительно производительности этого? Действительно ли это стоит того, чтобы сохранить страницы быстрыми и минимизировать трафик данных?
Как может я делать:
<input type="hidden" name="__VIEWSTATE" id="__VIEWSTATE"
value="/wEPDwUKMTM4Mjc3NDEyOWQYAQUeX19Db250cm9sc1JlcXVpcmVQb3N0QmFja0tleV9fFgkFLGN0b
DAwJENvbnRlbnRQbGFjZUhvbGRlcl9NYWluQ29udGVudCRSYWRCdXQxBSxjdGwwMCRDb250ZW50UGxhY2VIb
2xkZXJfTWFpbkNvbnRlbnQkUmFkQnV0MQUsY3RsMDAkQ29udGVudFBsYWNlSG9sZGVyX01haW5Db250ZW50J
FJhZEJ1dDIFLGN0bDAwJENvbnRlbnRQbGFjZUhvbGRlcl9NYWluQ29udGVudCRSYWRCdXQyBSxjdGwwMCRDb
250ZW50UGxhY2VIb2xkZXJfTWFpbkNvbnRlbnQkUmFkQnV0MwUsY3RsMDAkQ29udGVudFBsYWNlSG9sZGVyX
01haW5Db250ZW50JFJhZEJ1dDQFLGN0bDAwJENvbnRlbnRQbGFjZUhvbGRlcl9NYWluQ29udGVudCRSYWRCd
XQ0BSxjdGwwMCRDb250ZW50UGxhY2VIb2xkZXJfTWFpbkNvbnRlbnQkUmFkQnV0NQUsY3RsMDAkQ29udGVud
FBsYWNlSG9sZGVyX01haW5Db250ZW50JFJhZEJ1dDXz21BS0eJ7991pzjjj4VXbs2fGBw==" />
Во что-то как это:
<input type="hidden" name="__VIEWSTATE" id="__VIEWSTATE"
value="/wEPDwUKMTM4Mjc3N==" />
Опять же, после некоторого исследования этого я резюмировал свои выводы в блоге о сжатии состояния просмотра .
Вот что я сделал, чтобы сохранить сжатое состояние просмотра:
protected override void SavePageStateToPersistenceMedium(object state) {
SaveCompressedPageState(state);
}
private void SaveCompressedPageState(object state) {
byte[] viewStateBytes;
using(MemoryStream stream = new MemoryStream()) {
ObjectStateFormatter formatter = new ObjectStateFormatter();
formatter.Serialize(stream, state);
viewStateBytes = stream.ToArray();
}
byte[] compressed = CompressionHelper.Compress(viewStateBytes);
string compressedBase64 = Convert.ToBase64String(compressed);
ClientScript.RegisterHiddenField(ViewStateFieldName, compressedBase64);
}
И для части загрузки этот код заставил меня работать:
protected override object LoadPageStateFromPersistenceMedium() {
return LoadCompressedPageState();
}
private object LoadCompressedPageState() {
string viewState = Request.Form[ViewStateFieldName];
if(string.IsNullOrEmpty(viewState)) {
return string.Empty;
}
byte[] decompressed = CompressionHelper.Decompress(viewState);
string decompressedBase64 = Convert.ToBase64String(decompressed);
ObjectStateFormatter formatter = new ObjectStateFormatter();
return formatter.Deserialize(decompressedBase64);
}
Простой ответ может оказаться не тем, что вы хотите услышать. Слишком часто элементы управления на странице имеют состояние просмотра по умолчанию, когда им это действительно не нужно. Хорошая идея - отключить состояние просмотра до тех пор, пока вы не узнаете, что оно вам понадобится, и включайте его только (надеюсь) в тех немногих случаях, когда вы действительно хотите сохранить состояние просмотра.
public abstract class PageBase : System.Web.UI.Page
{
private ObjectStateFormatter _formatter = new ObjectStateFormatter();
private static byte[] Compress( byte[] data )
{
var compressedData = new MemoryStream();
var compressStream = new GZipStream(output, CompressionMode.Compress, true);
compressStream.Write(data, 0, data.Length);
compressStream.Close();
return compressedData.ToArray();
}
private static byte[] Uncompress( byte[] data )
{
var compressedData = new MemoryStream();
input.Write(compressedData, 0, compressedData.Length);
input.Position = 0;
var compressStream = new GZipStream(compressedData, CompressionMode.Decompress, true);
var uncompressedData = new MemoryStream();
var buffer = new byte[64];
var read = compressStream.Read(buffer, 0, buffer.Length);
while (read > 0)
{
uncompressedData.Write(buffer, 0, read);
read = compressStream.Read(buffer, 0, buffer.Length);
}
compressStream.Close();
return uncompressedData.ToArray();
}
protected override void SavePageStateToPersistenceMedium(object viewState)
{
var ms = new MemoryStream();
_formatter.Serialize(ms, viewState);
var viewStateBytes = ms.ToArray();
ClientScript.RegisterHiddenField("__COMPRESSED_VIEWSTATE"
, Convert.ToBase64String( Compress(viewStateArray)) );
}
protected override object LoadPageStateFromPersistenceMedium()
{
var compressedViewState = Request.Form["__COMPRESSED_VIEWSTATE"];
var bytes = Uncompress( Convert.FromBase64String( compressedViewState ) );
return _formatter.Deserialize( Convert.ToBase64String( bytes ) );
}
}
Лучший способ минимизировать состояние просмотра - просто не использовать его. Это заставит вас выполнить дополнительную работу по программированию (повторное заполнение контрольных значений и т. Д. При обратной публикации, но это сэкономит вам количество информации, которую вы отправляете в браузер). Вы не можете вмешиваться в это.
Вот ссылка на состояние просмотра в MSDN:
http://msdn.microsoft.com/en-us/library/ms972976.aspx
Вот ссылка, описывающая некоторые передовые практики:
http://mnairooz.blogspot.com/2007/01/aspnet-20-viewstate-and-good-practices.html
И еще один об отключении ViewState:
http://www.codeproject.com /KB/aspnet/ASPNET_Best_Practices.aspx
Себ, ViewState уже сжат... вот что вы видите... сжатую версию ваших элементов управления. Если вы хотите меньше накладных расходов, то не используйте viewstate :)
Использование ViewState должно быть сведено к минимуму!
Это визуализация вашего опубликованного состояния просмотра в формате XML:
<viewstate>
<Pair>
<Pair>
<String>1382774129</String>
</Pair>
</Pair>
</viewstate>
<controlstate>
<HybridDictionary>
<DictionaryEntry>
<String>__ControlsRequirePostBackKey__</String>
<ArrayList>
<String>ctl00$ContentPlaceHolder_MainContent$RadBut1</String>
<String>ctl00$ContentPlaceHolder_MainContent$RadBut1</String>
<String>ctl00$ContentPlaceHolder_MainContent$RadBut2</String>
<String>ctl00$ContentPlaceHolder_MainContent$RadBut2</String>
<String>ctl00$ContentPlaceHolder_MainContent$RadBut3</String>
<String>ctl00$ContentPlaceHolder_MainContent$RadBut4</String>
<String>ctl00$ContentPlaceHolder_MainContent$RadBut4</String>
<String>ctl00$ContentPlaceHolder_MainContent$RadBut5</String>
<String>ctl00$ContentPlaceHolder_MainContent$RadBut5</String>
</ArrayList>
</DictionaryEntry>
</HybridDictionary>
</controlstate>
По сути, это всего лишь несколько радиокнопок, которые хотят знать об их существовании. (браузеры не отправляют поле
с постданными, если оно не отмечено). Это уже довольно минимально.
Скорее всего, его можно сжать, подключив методы загрузки / сохранения или модули HTTP, но это может быть непрактично и не совсем необходимо.
В случае, если состояние просмотра намного больше в вашем реальном приложении, вообще избегайте получения объектов в состоянии просмотра. Это может быть достигнуто путем инициализации элементов управления в методах OnInit ()
или Page_Init ()
вместо стандартных Page_Load ()
.
Обоснование этого можно найти на странице http://weblogs.asp.net/infinitiesloop/archive/2006/08/03/Truly-Understanding-Viewstate.aspx { {1}} и http://msdn.microsoft.com/en-us/library/ms972976.aspx
Краткое резюме:
OnInit ()
будет вызван метод TrackViewState ()
. Page_Load ()
) или обработчика событий будут отслеживаться и отправляться клиенту. Таким образом, эти элементы управления могут восстановить свое состояние при следующем запросе. OnInit ()
. (например, повторное заполнение параметров DropDownList
из базы данных).Одно исключение:
Если элемент управления динамически добавляется в дерево элементов управления, он воспроизводит догоняющий. Их метод OnInit ()
может быть запущен позже, в результате чего эти свойства в конечном итоге окажутся в состоянии просмотра. Если инициализация элемента управления не может произойти в OnInit ()
, установка EnableViewState = "false"
может использоваться в качестве временного решения.
Каждый раз, когда мое состояние просмотра неожиданно увеличивается, я использую приложение «ViewState Decoder 2.2», чтобы узнать, что попало в состояние просмотра. Часто данные не нужны.
И последнее слово:
Состояние просмотра не используется для повторного заполнения форм !! Эти значения уже отправлены вместе с постданными.