One of the best articles I've seen on some of the solutions to this problem is here:
http://blogs.msdn.com/tom/archive/2008/03/14/validation-of-viewstate-mac-failed-error.aspx
There are 3 workarounds suggested:
- Set enableEventValidation to false and viewStateEncryptionMode to Never.
- Disable the form until the page has finished loading
function enableForm() {
document.getElementById("form").disabled = false;
}
window.onLoad = enableForm();
Or override the Render of your page so that the Encrypted section of the viewstate is put at the top of the form rather than at the bottom as it is by default. I've tested this version in our application which uses Virtual Earth maps and it fixes the issues with have with slow page loads (RECOMMENDED as it does not rely on javascript to work):
public abstract class BasePage : Framework.Web.UI.Pages.BasePage
{
/// <summary>
/// Fix for viewstate issue when the user clicks on a button before the encrypted section
/// of the viewstate is finished.
/// As per fix in
/// http://blogs.msdn.com/tom/archive/2008/03/14/validation-of-viewstate-mac-failed-error.aspx
/// </summary>
/// <param name="writer"></param>
protected override void Render(System.Web.UI.HtmlTextWriter writer)
{
System.IO.StringWriter stringWriter = new System.IO.StringWriter();
HtmlTextWriter htmlWriter = new HtmlTextWriter(stringWriter);
base.Render(htmlWriter);
string html = stringWriter.ToString();
string[] aspnet_formelems = new string[5];
aspnet_formelems[0] = "__EVENTTARGET";
aspnet_formelems[1] = "__EVENTARGUMENT";
aspnet_formelems[2] = "__VIEWSTATE";
aspnet_formelems[3] = "__EVENTVALIDATION"; aspnet_formelems[4] = "__VIEWSTATEENCRYPTED";
foreach (string elem in aspnet_formelems)
{
//Response.Write("input type=""hidden"" name=""" & abc.ToString & """")
int StartPoint = html.IndexOf("<input type=\"hidden\" name=\"" +
elem.ToString() + "\"");
if (StartPoint >= 0)
{
//does __VIEWSTATE exist?
int EndPoint = html.IndexOf("/>", StartPoint) + 2;
string ViewStateInput = html.Substring(StartPoint, EndPoint - StartPoint);
html = html.Remove(StartPoint, EndPoint - StartPoint);
int FormStart = html.IndexOf("<form");
int EndForm = html.IndexOf(">", FormStart) + 1;
if (EndForm >= 0)
html = html.Insert(EndForm, ViewStateInput);
}
}
writer.Write(html);
}