首先,让我们从一个事实开始,即这种视图状态错误发生在PostBack上。
此外,我必须说,我已经做了所有人建议的事情来避免这个问题。而且我只有一台机器,但有两个运行相同页面的池。
所以有人会执行某个操作,可能是一个人或其他搜索引擎通过“点击”你的页面,或者一些黑客试图检查你的系统是否存在问题...
我也遇到过类似的问题(虽然罕见但确实存在),最终发现人们试图对我的页面进行黑客测试(来自同一IP的Dos攻击)。
我修改了函数LoadPageStateFromPersistenceMedium(),将其翻译视图状态,并记录输入的具体内容以及来自哪些IP...然后我开始监控这些结果,发现视图状态被手动更改或完全为空。
出现错误时,我只需将其重定向到相同的页面...
以下是我所做的...
public abstract class BasePage : System.Web.UI.Page
{
protected override object LoadPageStateFromPersistenceMedium()
{
try
{
.. return the base, or make here your decompress, or what ever...
return base.LoadPageStateFromPersistenceMedium();
}
catch (Exception x)
{
string vsString = Request.Form[__VIEWSTATE];
string cThePage = Request.RawUrl;
...log the x.ToString() error...
...log the vsString...
...log the ip coming from...
...log the cThePage...
Debug.Fail("Fail to load view state ! Reason:" + x.ToString());
}
Responce.Redirect(Request.RawUrl, true);
return string.Empty;
}
}
第二个原因
现在还有一个原因会导致这种情况发生,那就是因为有人在__EVENTVALIDATION加载之前点击了您的页面。
这个eventValidation被放置在asp.net找到的最后一个按钮事件上,如果您在页面的许多位置或靠近按钮的地方有一些按钮事件,那么这个eventValidation会移到页面末尾。
因此,即使您在页面顶部看到了viewstate,但验证在哪里?也许这从未被加载过-页面损坏了吗?用户点击速度太快了吗?
<input type="hidden" name="__EVENTVALIDATION" id="__EVENTVALIDATION" ... >
为了避免这种问题,我编写了一个简单的JavaScript代码,只有在输入框加载完成后才能按下按钮!!!
另外,__EVENTVALIDATION并不总是存在!因此,如果您要制作通用解决方案,最好不要搜索此字段,而是使用JavaScript技巧来检查整个页面是否已加载或其他您认为合适的内容。
以下是我的最终解决方案,使用jQuery实现:(请注意,我在PageLoad上检查eventvalidation是否存在!)。我把它放在了我的MasterPages中。
<script language="javascript" type="text/javascript">
function AllowFormToRun()
{
var MyEventValidation = $("#__EVENTVALIDATION");
if(MyEventValidation.length == 0 || MyEventValidation.val() == ""){
alert("Please wait for the page to fully loaded.");
return false;
}
return true;
}
</script>
protected void Page_Load(object sender, EventArgs e)
{
if (Page != null && Page.EnableEventValidation)
{
Form.Attributes["onsubmit"] = "return AllowFormToRun();";
}
}
你可以通过在页面按钮附近设置延迟来进行测试。
<% System.Threading.Thread.Sleep(5000); %>
更新
今天我在日志中再次看到WebResource的这条消息,并发现一只机器人获取页面并将链接中的所有字符都转为小写,包括参数。所以这是导致未正确编码字符串和出现填充无效且无法删除消息的更多原因之一。
希望这能对您有所帮助。