首先让我们从这样一个事实开始,即这种视图状态错误发生在 PostBack 上。
另外我必须说,我已经做了每个人建议做的所有事情来避免这个问题。而且我有单台机器,但有 2 个运行相同页面的池。
因此,有人通过“单击”您的页面来执行操作,以太人,以太其他搜索机器,或者某些黑客试图检查您的系统是否存在问题......
我有类似的问题(罕见但存在的问题),我终于发现人们试图对我的页面进行黑客测试。(来自我拥有的同一个 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...
// check by your self for local errors
Debug.Fail("Fail to load view state ! Reason:" + x.ToString());
}
// if reach here, then have fail, so I reload the page - maybe here you
// can place somthing like ?rnd=RandomNumber&ErrorId=1 and show a message
Responce.Redirect(Request.RawUrl, true);
// the return is not used after the redirect
return string.Empty;
}
}
第二个原因
现在还有一个原因会发生这种情况,原因是在加载 __EVENTVALIDATION 之前有人单击了您的页面。
这个 eventValidation 被放置在最后一个按钮上——即使是 asp.net 找到的那个按钮,如果你在页面上的很多地方或者按钮附近有一些按钮,那么它会转到页面的末尾。
所以即使你看到页面顶部的视图状态,验证在哪里???也许这从未加载过 - 页面损坏?,用户点击页面太快?
<input type="hidden" name="__EVENTVALIDATION" id="__EVENTVALIDATION" ... >
为避免此类问题,我制作了一个简单的 javascript,除非已加载此输入,否则我不会让它按下按钮!!!。
还有一条评论,__EVENTVALIDATION 并不总是存在!因此,如果您制定通用解决方案,则不要搜索此字段可能更安全,而是制作一个 javascript 技巧来检查是否已加载整个页面或您认为的其他内容。
这是我使用 jQuery 的最终解决方案:(请注意,如果 eventvalidation 存在,我会检查 PageLoad!)。我把它放在我的 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)
{
// I do not know if Page can be null - just in case I place it.
if (Page != null && Page.EnableEventValidation)
{
Form.Attributes["onsubmit"] = "return AllowFormToRun();";
}
}
您可以通过在页面按钮附近放置延迟来进行测试。
<% System.Threading.Thread.Sleep(5000); %>
更新
今天我在日志中再次看到 WebResource 的这条消息,我发现机器人获取页面并将链接上的所有字符(包括参数)都设为小写,所以这是没有获得正确编码字符串的另一个原因, 并抛出Padding is invalid and cannot be removed 之类的消息。
希望这对您有更多帮助。