Как удалить или сжать ваше viewstate asp.net
Просто потратил много времени, изгнав asp.net большое (но понятно полезное) viewstate из приложения, и я думаю, что стоит поделиться тем, как это делается.
В принципе, я хочу, чтобы этот вопрос был открыт для всех решений для сжатия/сжатия/удаления viewstate.
Ответы
Ответ 1
Еще один лучший вариант: сверните свой собственный PageStatePersister. Здесь мой, сильно вдохновленный http://aspalliance.com/72:
using System.Web.UI;
... in your page class:
PageStatePersister pageStatePersister;
protected override PageStatePersister PageStatePersister
{
get
{
// Unlike as exemplified in the MSDN docs, we cannot simply return a new PageStatePersister
// every call to this property, as it causes problems
return pageStatePersister ?? (pageStatePersister = new BetterSessionPageStatePersister(this));
}
}
... in your BetterSessionPageStatePersister.cs:
/// <summary>
/// This class allows the viewstate to be kept server-side, so that postbacks are as small as possible.
/// It is similar to the built-in 'SessionPageStatePersister', but it yields smaller postbacks,
/// because the SessionPageStatePersister still leaves some viewstate (possibly it leaves the controlstate)
/// in the postback.
/// </summary>
class BetterSessionPageStatePersister : PageStatePersister
{
public BetterSessionPageStatePersister(Page page)
: base(page)
{ }
const string ViewStateFieldName = "__VIEWSTATEKEY";
const string ViewStateKeyPrefix = "ViewState_";
const string RecentViewStateQueue = "ViewStateQueue";
const int RecentViewStateQueueMaxLength = 5;
public override void Load()
{
// The cache key for this viewstate is stored in a hidden field, so grab it
string viewStateKey = Page.Request.Form[ViewStateFieldName] as string;
// Grab the viewstate data using the key to look it up
if (viewStateKey != null)
{
Pair p = (Pair)Page.Session[viewStateKey];
ViewState = p.First;
ControlState = p.Second;
}
}
public override void Save()
{
// Give this viewstate a random key
string viewStateKey = ViewStateKeyPrefix + Guid.NewGuid().ToString();
// Store the view and control state
Page.Session[viewStateKey] = new Pair(ViewState, ControlState);
// Store the viewstate key in a hidden field, so on postback we can grab it from the cache
Page.ClientScript.RegisterHiddenField(ViewStateFieldName, viewStateKey);
// Some tidying up: keep track of the X most recent viewstates for this user, and remove old ones
var recent = Page.Session[RecentViewStateQueue] as Queue<string>;
if (recent == null) Page.Session[RecentViewStateQueue] = recent = new Queue<string>();
recent.Enqueue(viewStateKey); // Add this new one so it'll get removed later
while (recent.Count > RecentViewStateQueueMaxLength) // If we've got lots in the queue, remove the old ones
Page.Session.Remove(recent.Dequeue());
}
}
Ответ 2
Первый простой вариант, используйте встроенный класс SessionPageStatePersister. Это делает сохранение состояния просмотра в сеансе на сервере, а не отправку его клиенту. Тем не менее, он по-прежнему отправляет меньше viewstate вниз, поэтому не все розы:
using System.Web.UI;
... the following goes in your Page class (eg your .aspx.cs) ...
PageStatePersister pageStatePersister;
protected override PageStatePersister PageStatePersister
{
get
{
// Unlike as exemplified in the MSDN docs, we cannot simply return a new PageStatePersister
// every call to this property, as it causes problems
return pageStatePersister ?? (pageStatePersister = new SessionPageStatePersister(this));
}
}
Этот метод уменьшил особенно большую отдачу от 100 к до 80 тыс. Не здорово, но хорошее начало.
Ответ 3
Переключитесь на ASP.NET MVC!
Нет ViewState!
Ответ 4
Важно сначала понять, что это за образцовое представление, и почему вы хотите его в первую очередь. После этого просто нужно помнить о том, что приложение делает для вас, и помнить о том, чтобы прикрепить UseViewState = "false" ко всем элементам, которые обычно будут использовать viewstate.
Теперь, чтобы запомнить, почему это полезно, у вас будет определенная потребность чаще извлекать вещи вручную.
Время и место для всех инструментов, да?
Ответ 5
Полностью избавиться от него:
protected override object LoadPageStateFromPersistenceMedium()
{
return null;
}
protected override void SavePageStateToPersistenceMedium(object viewState)
{
}
Ответ 6
Вы можете попробовать it или it!
Ответ 7
Вы можете с небольшим обманом захватить только сериализацию состояния страницы, получив из System.Web.Page и переопределив свойство PageStatePersister:
private PageStatePersister _pageStatePersister = null;
protected override PageStatePersister PageStatePersister
{
get { return _pageStatePersister ?? (_pageStatePersister = new PersistState(this)); }
}
Как только вы это сделаете, вы можете получить новый экземпляр из HiddenFieldPageStatePersister и оттуда использовать отражение для изменения реализации сохранения:
class PersistState : HiddenFieldPageStatePersister, IStateFormatter
{
public PersistState(Page p) : base(p)
{
FieldInfo f = typeof(PageStatePersister).GetField("_stateFormatter", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.SetField);
f.SetValue(this, this);
}
object IStateFormatter.Deserialize(string serializedState)
{
BinaryFormatter f = new BinaryFormatter();
using (GZipStream gz = new GZipStream(new MemoryStream(Convert.FromBase64String(serializedState)), CompressionMode.Decompress, false))
return f.Deserialize(gz);
}
string IStateFormatter.Serialize(object state)
{
BinaryFormatter f = new BinaryFormatter();
using (MemoryStream ms = new MemoryStream())
{
using (GZipStream gz = new GZipStream(ms, CompressionMode.Compress, true))
f.Serialize(gz, state);
return Convert.ToBase64String(ms.ToArray());
}
}
}
BEWARE
Это пример только для исследовательских целей. Вышеприведенный код является ОБЕСПЕЧЕНИЕМ БЕЗОПАСНОСТИ, поскольку он не подписывает и не шифрует полезную нагрузку, и поэтому его можно легко взломать любым, кто пытается причинить вред вашему сайту.
Снова НЕ ИСПОЛЬЗУЙТЕ ЭТОТ КОД без полного и полного понимания безопасности, криптографии и сериализации .Net.
</warning>
Реальная проблема, как говорили другие, заключается в использовании состояния страницы для начала. Простейшим решением для плохо написанного приложения ASP.NET, которое сильно использует состояние страницы, является поддержка государственного сервера и использование SessionPageStatePersister.
Ответ 8
Один из методов, который мы использовали в моей компании, - удалить большую часть из них, удалив вызовы runat="server"
. Затем мы используем javascript или хорошую библиотеку javascript, такую как jQuery или Prototype, для заполнения элементов HTML с помощью аякс-вызовов на сервере.
Мой босс проделал большую работу с веб-сайтом, на котором было несколько мегабайт данных viewstate. Он использовал вышеупомянутый метод, и он "отлично работает без просмотра".