Getting asp.net to store viewstate in the session rather than bulking up the html

后端 未结 3 583
悲哀的现实
悲哀的现实 2020-12-18 00:53

I\'m trying to get asp.net to store viewstate in the session rather than bulking up the html.

Now i\'ve read that asp.net comes with the SessionPageStatePersister wh

相关标签:
3条回答
  • 2020-12-18 00:53

    You sure you want to do this? There are problems

    1. How do you keep individual pages apart? Sure, you can prefix the session state name with the page, eg. Session["/default.aspx-Viewstate"] but what happens when the user has multiple instances of a page open?
    2. So to solve that you put a hidden field with, say, a GUID in each page, which you then use as a key. So your session size grows. And grows. And grows. How will you know if/when you can remove things safely?

    If you insist on heading down this read then all you need to do is derive a class from page and override LoadPageStateFromPersistenceMedium() and SavePageStateToPersistenceMedium(). But you'll hate yourself and rip it out eventually.

    Just make sure you have HTTP compression turned on at your server, and please, worry about something else instead.

    0 讨论(0)
  • 2020-12-18 01:00

    For what it's worth, here's the code i ended up using to solve the big-picture problem at hand: moving viewstate out of the html. Just pop this into your mypage.aspx.cs:

    // Inspired by: http://aspalliance.com/72
    const string ViewStateFieldName = "__VIEWSTATEKEY";
    const string RecentViewStateQueue = "RecentViewStateQueue";
    const int RecentViewStateQueueMaxLength = 5;
    
    protected override object LoadPageStateFromPersistenceMedium()
    {
        // The cache key for this viewstate is stored where the viewstate normally is, so grab it
        string viewStateKey = Request.Form[ViewStateFieldName] as string;
        if (viewStateKey == null) return null;
    
        // Grab the viewstate data from the cache using the key to look it up
        string viewStateData = Cache[viewStateKey] as string;
        if (viewStateData == null) return null;
    
        // Deserialise it
        return new LosFormatter().Deserialize(viewStateData);
    }
    
    protected override void SavePageStateToPersistenceMedium(object viewState)
    {
        // Serialise the viewstate information
        StringBuilder _viewState = new StringBuilder();
        StringWriter _writer = new StringWriter(_viewState);
        new LosFormatter().Serialize(_writer, viewState);
    
        // Give this viewstate a random key
        string viewStateKey = Guid.NewGuid().ToString();
    
        // Store the viewstate in the cache
        Cache.Add(viewStateKey, _viewState.ToString(), null, Cache.NoAbsoluteExpiration, TimeSpan.FromMinutes(Session.Timeout), CacheItemPriority.Normal, null);
    
        // Store the viewstate's cache key in the viewstate hidden field, so on postback we can grab it from the cache
        ClientScript.RegisterHiddenField(ViewStateFieldName, viewStateKey);
    
        // Some tidying up: keep track of the X most recent viewstates for this user, and remove old ones
        var recent = Session[RecentViewStateQueue] as Queue<string>;
        if (recent == null) 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
        Cache.Remove(recent.Dequeue());
    }
    

    And for a super-simple way of using the SessionPageStatePersister, again put this in your mypage.aspx.cs:

    protected override PageStatePersister PageStatePersister
    {
        get
        {
            return new SessionPageStatePersister(this);
        }
    }
    
    0 讨论(0)
  • 2020-12-18 01:04

    In order to use your custom PageAdapter class you have to register it with .browser file. You need to add (if you don't already have) a App_Browsers directory. Then add a .browser file with following XML

    <browsers>
        <browser refID="Default">
            <controlAdapters>
               <adapter controlType="System.Web.UI.Page" adapterType="{Your adapter type}" />
            </controlAdapters>
        </browser>
    </browsers> 
    

    replace {Your adapter type} with your adapter type.

    More information here

    Hope this helps.

    0 讨论(0)
提交回复
热议问题