如何删除或压缩您的asp.net视图状态

Chr*_*ris 10 c# asp.net viewstate

花了很多时间从应用程序中驱逐asp.net的大型(但可以理解的有用)视图状态,我认为值得分享它是如何完成的.

基本上,我希望这个问题对缩小/压缩/删除视图状态的所有解决方案开放.

Chr*_*ris 7

第一个简单的选项,使用内置的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));
  }
}
Run Code Online (Sandbox Code Playgroud)

这种方法将一个特别大的回发从100k缩小到80k.不是很好,但是一个好的开始.


Sim*_*ver 6

切换到ASP.NET MVC! 没有ViewState!

  • 对于使用viewstate的现有站点的人来说,它可能没用,但是:我不禁同意你的看法. (4认同)
  • (我不认为这应该是downvotes) (4认同)

Chr*_*ris 5

另一个更好的选择,滚动你自己的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's 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());
  }
}
Run Code Online (Sandbox Code Playgroud)