views:

366

answers:

2

An interesting take on an error that's really fustrating. I have a MVC page with no runat=server controls, a single form, and yet I have still recieved a "Validation of viewstate MAC failed" exception on the page, when reading through my error logs.

Here is the exception thrown:

System.Web.HttpException: Validation of viewstate MAC failed. If this application is hosted by a Web Farm or cluster, ensure that <machineKey> configuration specifies the same validationKey and validation algorithm. AutoGenerate cannot be used in a cluster. ---> System.Web.UI.ViewStateException: Invalid viewstate.
Client IP: 10.XXX.XXX.XXX Port: 33791 
User-Agent: Mozilla/5.0 (Windows; U; Windows NT 6.0; en-US; rv:1.9.1.5) Gecko/20091102 Firefox/3.5.5 (.NET CLR 3.5.30729) 
ViewState: /wEPDwUKMTc2MzIxNTAwOWRkLTq4ngVrnkwCLjQCKKiLdjGVFbs=

Here is the complete stack:

System.Web.HttpException: Validation of viewstate MAC failed. If this application is hosted by a Web Farm or cluster, ensure that <machineKey> configuration specifies the same validationKey and validation algorithm. AutoGenerate cannot be used in a cluster. ---> System.Web.UI.ViewStateException: Invalid viewstate. 
    Client IP: 10.XXX.XXX.XXX
    Port: 33791
    User-Agent: Mozilla/5.0 (Windows; U; Windows NT 6.0; en-US; rv:1.9.1.5) Gecko/20091102 Firefox/3.5.5 (.NET CLR 3.5.30729)
    ViewState: /wEPDwUKMTc2MzIxNTAwOWRkLTq4ngVrnkwCLjQCKKiLdjGVFbs=
    Referer: http://www.shelfari.com/search/combine?Keywords=turn%20of%20the%20screw
    Path: /search/Combine ---> System.Web.HttpException: Unable to validate data.
   at System.Web.Configuration.MachineKeySection.GetDecodedData(Byte[] buf, Byte[] modifier, Int32 start, Int32 length, Int32& dataLength)
   at System.Web.UI.ObjectStateFormatter.Deserialize(String inputString)
   --- End of inner exception stack trace ---
   --- End of inner exception stack trace ---
   at System.Web.UI.ViewStateException.ThrowError(Exception inner, String persistedState, String errorPageMessage, Boolean macValidationError)
   at System.Web.UI.ObjectStateFormatter.Deserialize(String inputString)
   at System.Web.UI.Util.DeserializeWithAssert(IStateFormatter formatter, String serializedState)
   at System.Web.UI.HiddenFieldPageStatePersister.Load()
   at System.Web.UI.Page.LoadPageStateFromPersistenceMedium()
   at System.Web.UI.Page.LoadAllState()
   at System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint)
   at System.Web.UI.Page.ProcessRequest(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint)
   at System.Web.UI.Page.ProcessRequest()
   at System.Web.UI.Page.ProcessRequest(HttpContext context)
   at ASP.views_search_bookcombined_aspx.ProcessRequest(HttpContext context)
   at System.Web.Mvc.ViewPage.RenderView(ViewContext viewContext)
   at System.Web.Mvc.ViewResultBase.ExecuteResult(ControllerContext context)
   at System.Web.Mvc.ControllerActionInvoker.<>c__DisplayClass11.<InvokeActionResultWithFilters>b__e()
   at System.Web.Mvc.ControllerActionInvoker.InvokeActionResultFilter(IResultFilter filter, ResultExecutingContext preContext, Func`1 continuation)
   at System.Web.Mvc.ControllerActionInvoker.InvokeActionResultWithFilters(ControllerContext controllerContext, IList`1 filters, ActionResult actionResult)
   at System.Web.Mvc.ControllerActionInvoker.InvokeAction(ControllerContext controllerContext, String actionName)
   at System.Web.Mvc.Controller.ExecuteCore()
   at System.Web.Mvc.MvcHandler.ProcessRequest(HttpContextBase httpContext)
   at System.Web.HttpApplication.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute()
   at System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously)

It's not clear why there would be viewstate on the page at all - I've never been able to reproduce the error, but it occurs occasionally in logs. The users who get the error tend to be individuals trusted & unlikely to be manipulating the viewstate manually.

The production environment is a webfarm, with machineKey configuration specified, using the validationKey and validation algorithm across all machines.

Any thoughts?

+4  A: 

I've seen this too. I believe the cause is search engine accesses -- something must be missing in the way that the search engine accesses the page. At least the issue went away when I added a robots.txt file and told the search engines not to spider my login page (with the form and antiforgery token).

tvanfosson
Interesting! .....
womp
Interesting, but unlikely to be the case here. The page in question is only visible to authenticated users (ruling out spiders), and isn't a place one would normally bookmark or cache - it's a page that allows editing of search results (mostly ruling out cache problems)
Kevin
Perhaps it's the result of the antiforgery cookie timing out and then the form being submitted. This would be, perhaps, consistent with a search engine simply not submitting the antiforgery cookie with the request.
tvanfosson
@tvanfosson, From what I understand the AntiForgertyToken needs to be manually rendered to the page in question - which I am not doing for this particular page. It's worth noting that the problem occurs for authenticated users, admins, actually...
Kevin
A: 

You can try to disable validating viewstate at all views with web.config located in Views directory (section pages).

You can disable all other WebForms "futures" like AutoEventWireup :)

dario-g
That may work, but it's not going to be pratical for me. I run a mixed website, where my master template is an MVC view (under views directory), but also have pages that rely on viewstate. In testing, it seems that disabling viewstate on the views directory did break functionality, even though those pages were outside of the view dir.
Kevin