Many ASP.Net Websites use Viewstate to exchange the state of controls on a Page between the Client and the Server, as this works to build web applications that retain the concept of state-fullness or the user’s current page-state between Postbacks into what is the fundamental stateless nature of the web.

Viewstate is then posted back from the client to the server within the body of the page, employing a simple hidden <input> tag to transmit the block of ViewState detail back from the Client to the Server, which the Server then processes to build the Page Appearance and transmit back to the client – this fits into the traditional Request (from client) and Response (back from the server) view of the world that HTML and Web Frameworks typically operate from.

<input type=”hidden” name=”__VIEWSTATE” id=”__VIEWSTATE” value=”MyViewState” />

However where we see ‘MyViewState’ in the above HTML code, this will instead be a long series of Hexdecimal Characters that describe the ViewState being posted from the Client to the Server.  For performance and security this block of characters is hash encrypted and hence the real viewstate that ASP.NET uses is translated into this block of (seemingly meaningless) characters – however this allows ASP.NET to encrypt and decrypt this block into the real Viewstate using a particular Encryption Key.

By default ASP.NET will generate this Encryption Key between the Client and Server upon each request so the communication follows a secure path.

However in a scenario where we are using multiple Web Servers or a Web Farm, this can lead to the following error:

image

This is due to the way that the View State may be being generated against one Web Server using a particular Encryption Key and then reposted to a different Web Server that is using a separate and different Encryption Key – leading to an error between the two different Encryption Keys as the key in use at the Client may not match the Key at the Server in this Load Balancing arrangement.

In effect, giving us the following scenario:

1.       User accesses Webpage via Web Server A – receives Encryption Key from A

2.       User posts back Webpage to Web Server A – with Web Server A validating the Encryption Key correctly – no error to the user

3.       User posts back the Webpage again, and the Load Balancing / Web Farm directs the Request to Web Server B instead – Web Server B then tries to decrypt the Viewstate using it’s own Encryption Key, finds the difference between Key A and Key B and so throws this error – user is then presented with the error

The resolution to this is similar to ensuring Session State is consistent when using Load Balancers and Web Farms – ensuring that a common Encryption Key exists between both Servers A and B, giving us a single key that both A and B use to manage Viewstate to make which Server the User is requesting from irrelevant.

How do we do this?

To put this common key in place, we need to run through two steps:

1.       Generate the Key – we access Powershell on the selected Server and run the following command:

Generate-MachineKey

                This will generate a new Encryption Key in the form that can be used in our Web Application.

                                <machineKey decryption=”AES” decryptionKey=”ABC” validation=”SHA1″ validationKey=”DEF” />

2.       Insert this key into our Web Application – we then need to access the Web.Config on each of our Load Balanced Web Servers and add the <machineKey> tag into the configuration under the <system.web> section:

<configuration>

<system.web>

<machineKey decryption=”AES” decryptionKey=”ABC” validation=”SHA1″ validationKey=”DEF” />

                The key here being to ensure that each Server is using the same ‘decryptionKey’ and ‘encryptionKey’ as generated by the Powershell.

With these two steps in place, the Web Servers should share the same Encryption Key for Viewstate and so this error should no longer occur.

Further Reading

This encryption of ViewState is a common part of the ASP.Net Framework and so have many articles and useful reading across the web, particularly from Microsoft and MSDN.  The links below give a more detailed set of information on this topic.

Resolving View State Message Authentication Code (MAC) errors

https://support.microsoft.com/en-us/kb/2915218#bookmark-appendixa

Machine Key Element in ASP.NET

https://msdn.microsoft.com/library/w8h3skw9(v=vs.100).aspx

Generating your Machine Key from IIS 7

https://blogs.msdn.com/b/vijaysk/archive/2009/05/13/iis-7-tip-10-you-can-generate-machine-keys-from-the-iis-manager.aspx

Author

Write A Comment