问题
I have an ASP.net 3.5 sp1 web application that is running on IIS6 and has the machine and validation keys set in the web config. The application functions correctly on all browsers except safari.
The page loads correctly but when a postback is performed I receive a "Validation of Viewstate MAC failed" error. (Also, the app pool only recycles once a day during the night but this shouldn't make a difference as the keys are fixed.)
I have found several suggestions on the internet including limiting the size of the viewstate fields via the web config and also disabling Prefetch within safari - non of which have worked.
I have found other posts on Stackoverflow but non of them helped in resolving the issue.
Is this a known issue with safari or has anyone else encountered this problem ?
回答1:
We had a similar problem start on Mar 12, 2012 which is the day tha Safari 5.1.4 was released. The problem occurs in Safari 5.1.5 as well. It happens on both windows and mac versions of safari.
In our case the viewstate being submit by Safari was a complete viewstate, unfortunately it was for the previous page rather than the page being posted.
To verify this
- First before submitting, check the view state by viewing source on the page experiencing the problem. This is typically base64 encoded and may be encrypted. If your site has it encrypted you may need to turn this off to check the view state. You can search the internet for a base 64 decoder, there are several sites that you can paste the __Viewstate string into and decode it.
- Submit the page and recieve the error. If you get the custom error in the browser it will show you the viewstate value that was recieved by the server. If not go to the applicaiton event log on the server and find the logged error message. Decode the viewstate in the message in the same way as you did in step 1.
- Examine the contents of both viewstates, usually you will be able to tell by the data whether the viewstate belongs to the page being posted to or some other page.
So if you find they are different, you are probably experiencing the problem we were experiencing.
In our case the offending code that caused the problem was actually on the previous page. In PageOne we hooked in window.onload event and were calling form[0].submit. The server responded with a 302 redirect to PageTwo.aspx. The browser properly responded by performing a GET of Page2.aspx. When the user pressed the submit button on PageTwo.aspx the validation error occurs, in our case safari was submitting the value of the viewstate for the previous page, pageone.aspx
In our case we worked around the problem by calling setTimeout("DoWork()",10); in the window.onload event. Then put our code in the DoWork() function.
We have submitted a bug report to Apple.
Hope this helps.
回答2:
If on OSX, Try to make sure that the "Block Cookies: Always" radio button is not selected. You can find it in the Privacy tab of Preferences...
回答3:
First off, it is an anti-pattern to havve large viewstate (ie, let the page handle state in a postback). When there is a viewstate MAC issue, it has something to do with being unable to unencrypt the viewstate that is returned. Not sure whether safari for WIndows does this (likely, as I would imagine it is the same code base), but view state on the Mac is 1/4th the size of viewstate in PC oriented browsers (1K versus 4k).
Limiting the size of viewstatein config will only work if you can actually limit the size and still have your application work. And you have to limit within the 1K window (note this does not mean viewstate == 1K, as there are likely to be other things submitted back).
A better solution is to figure out what you have in viewstate and determine if you can rebind on the server side rather than rely on viewstate to automagically rebind. There is a SessionPageStatePersister that can be used.
The short answer is you will have to re-architect a bit to get passed this.
来源:https://stackoverflow.com/questions/9892840/asp-net-viewstate-with-safari-5-x