Persist the ViewState and Increase ASP.NET Performance

At the Richmond Code Camp I went over some of my tips and tricks to get ASP.NET to perform as fast as possible.  One of the biggest things you have to do is reduce the size of your ViewState and also move it to the bottom of the page.  It was brought to my attention that the View State can be stripped entirely from the page as it is being sent to the client (well sort of) and stored or persisted as a local file.  I found Dino Esposito's Cutting Edge article on working with the ViewState where he demonstrates this principle.

I tried this with some code to see what happened and I was pleasently surprised that this was pretty quick and did not produce any ViewState related exceptions for me.  Let's take a look, first at the original ViewState for a page:

<input type="hidden" name="__VIEWSTATE" id="__VIEWSTATE" value="/wEPDwUJMTE2MTg3NTYyDs2QWAmYPZBYCAgEPZBYCAg4PZBYCAgEP

ZBYEZg9kFgQCAw8QZGQWAQIdBZAIfDxQrAAJkZGQCAQ9kFgQCAQ8WAh4HVmlza

WJsZWgWAgIBD2QWAgIBD2QWAgIFsDw8WAh4ISW1hZ2VVcmwFKmh0dHA6Ly9sb2

NhbGhvc3QvbWFjL2ltYWdlcy9jb250YWdN0XzMyLmdpZmRkAgUPZBYEAgEPFgIfAGcW

BAICD2QWAgIBDxYCHgRUZXh0BQ9MdaW5kYSBEZW1lcml0dGVkAgQPZBYEAgMPF

gIfAGcWAgICD2QWAgIBDxYCHwIFCfUFsYW4gSHVudGQCBQ8PFgIfAGhkZAICD2QW

AmYPZBYCAgEPFgIfAGhkGAEFJGNf0bDAwJENvbnRlbnRQbGFjZUhvbGRlcjEkTXVsdG

lWaWV3MQ8PZAIBZBLDmk8f72Yt1WKBfAWhD8KS0hJhM" />

Now this is the ViewState Input tag using the PageState Persistance:

<input type="hidden" name="__VIEWSTATE" id="
__VIEWSTATE" value="" /> 

As you can see this is quite an improvement.  What happens is a file is created on the web server that contains the Page's ViewState.  The file contains the following text and is named after the session state.

/wEPGAEFJGN0bDAwJENvbnRlbnRQbGFjZUhvbGRlcjfEkTXVsdGlWaWV3MQ8PZAIBZA8FCTExNjE4Nz

U2Mg9kFgJmD2QWAgIBD2QWAgIOD2QWAgIBD2QWBGfYPZBYEAgMPEGRkFgECAWQCHw8UKwAC

ZGRkAgEPZBYEAgEPFgIeB1Zpc2libGVoFgICAQ9kFgICAQf9kFgICBQ8PFgIeCEltYWdlVXJsBSpodHRw

Oi8vbG9jYWxob3N0L21hYy9pbWFnZXMvY29udGFjdF8zMi5naWZkZAIFD2QWBAIBDxYCHwBnFgQCAg

9kFgICAQ8WAh4EVGV4dAUPTGluZGEgRGVtZfXJpdHRlZAIED2QWBAIDDxYCHwBnFgICAg9kFgICAQ8

WAh8CBQlBbGFuIEh1bnRkAgUPDxYCHwBofZGQCAg9kFgJmD2QWAgIBDxYCHwBoZA==

Now this leaves a problem because the ViewState files are bound to build up.  So you will have to build a purging mechanism into the web application to keep the directory as clean as possible.  For security purposes you also may not be allowed to store media either created on the fly or uploaded by users from the web.  I decided a good way to counter this problem would be to store the ViewState in cache with a dependancy.  This of course causes considerations for memory usage, so you will have to decide what is the most important in your situation.

I like to use the Enterprise Library to handle my Caching needs, so you will need to investigate this on your on, or wait will I get a chance to Blog about using the Caching block.  But until then, trust me this works.  The methodology relies on two special methods being created.  I created these methods to abstract the methodology out of the two Page class methods that need to be overriden.  I also created a utility method to return the sessionid as a name for the Cache variable, again just to abstract this out.

 

   

Protected

Function

LoadPageStateFromCache()

As

Object

 

       

Dim

m_viewState

As

String

       

Dim

m_formatter

As

LosFormatter

       

Dim

viewStateBag

As

Object

 

       

Dim

pc

As

CacheManager = CacheFactory.GetCacheManager()

 

       

Dim

sRequestContent

As

String

=

DirectCast

(pc.GetData(GetCacheName),

String

)

 

       

If

String

.IsNullOrEmpty(sRequestContent) =

False

Then

 

           

Dim

sr

As

New

StringReader(sRequestContent)

            m_viewState = sr.ReadToEnd()

            sr.Close()

 

            m_formatter =

New

LosFormatter()

 

            viewStateBag = m_formatter.Deserialize(m_viewState)

 

       

End

If

 

       

Return

String

.Empty

 

   

End

Function

 

   

Protected

Sub

SavePageStateToCache(

ByVal

viewStateBag

As

Object

)

 

       

Dim

m_formatter

As

LosFormatter =

New

LosFormatter()

       

Dim

stw

As

StringWriter =

New

StringWriter

        m_formatter.Serialize(stw, viewStateBag)

       

Dim

primitivesCache

As

CacheManager = CacheFactory.GetCacheManager()

        primitivesCache.Add(GetCacheName, stw.ToString(), CacheItemPriority.Normal,

New

ExCacheRefreshAction, _

           

New

AbsoluteTime(DateAdd(DateInterval.Minute, Session.Timeout + 30, Now())))

 

   

End

Sub

 

   

Protected

Overloads

Overrides

Function

LoadPageStateFromPersistenceMedium()

As

Object

 

       

Return

LoadPageStateFromCache()

       

'Return LoadPageStateFromFile()

       

'Return MyBase.LoadPageStateFromPersistenceMedium()

 

   

End

Function

 

   

Protected

Overloads

Overrides

Sub

SavePageStateToPersistenceMedium(

ByVal

viewStateBag

As

Object

)

 

        SavePageStateToCache(viewStateBag)

       

'SavePageStateToFile(viewStateBag)

       

'MyBase.SavePageStateToPersistenceMedium(viewStateBag)

 

   

End

Sub

 

   

Private

Function

GetCacheName()

As

String

       

Return

Session.SessionID.ToString

   

End

Function

One trick I do, just to be a little safe is to tell the Cache dependancy to keep the value in memory for 30 minutes past the session timeout.  What this will lead us to is creating a handler to let the user know their session has timed out.  I know I am real bad about always having my computer on and on about 20 pages all the time.  That means that many of these stateless pages will eventually cause a post back to the server when I get back to it.  My online banking application does this if I leave it running without a postback in say 10 minutes, so it is a common scenario to handle.  That will lead to another Blog entry.  I hope to have that ready by the NJ Code Camp this weekend.

 

Share This Article With Your Friends!

Googles Ads Facebook Pixel Bing Pixel LinkedIn Pixel