回发或回调参数无效(译)

1.问题描述


        这是个很多 ASP.NET 初学者都会遇到的问题。通常,他们会附上类似下图的错误消息去寻找解决方法,最后忘了分享他们当时是怎么解决的。
        虽然错误信息中提供了一个简单的解决方法:EnableEventValidation="flase"。但并不推荐,因为它会引发一个安全漏洞。最好的解决办法是探究它发生的根本原因。

2.说明


        事件验证(Event Validation)是为了验证事件的起源是否是相关的呈现控件 (而不是跨站点脚本之类的东西)。因为服务器控件在渲染时注册事件,事件可以在回发或回调中 (通过 __doPostBack 参数) 进行验证。这样做可以降低未经授权或恶意回发、回调的风险。

3.三种常见情况和解决方法


        基于上述内容,我遇到过和听过的可能引发回发或回调参数无效错误的三种情况如下

1.第一种

        在我们的请求数据中有尖括号,因为它看起来就像在将脚本标记传递给服务器
 
        解决方法:在提交form前借助JavaScript对尖括号进行编码,例如用"&lt"替代"<",用"&gt"替代">"
function HTMLEncodeAngularBrackets(someString)
{
    var modifiedString = someString.replace("<","&lt;");
    modifiedString = modifiedString.replace(">","&gt;");
    return modifiedString;
}
        PS:类似的一种情况是DropDownList控件的ListItem的Value属性包含汉字。可以通过在Web.config中添加如下语句
<globalization requestEncoding="utf-8" responseEncoding="utf-8" culture="zh-CN" uiCulture="zh-CN"/>
因为回发(PostBack)需要使用UTF-8 编码。

2.第二种

        如果我们写了一段在运行时更改客服端控件的后台代码,就可能遇到这种情况。比如一里一外两个控件(内部控件运行时隐藏),对外部控件的一个操作引发内部控件去注册回发,最终抛出错误。这个问题我在Carlo的MSDN博客中也看到过。
 
        解决方法︰通过重写Page的Render方法,手动注册控件的事件验证
protectedoverridevoidRender(HtmlTextWriter writer)
{
    ClientScript.RegisterForEventValidation(myButton.UniqueID.ToString());
    base.Render(writer);
}
        另一种常见情况就是 (看上去应该归在这类中)一个form标签嵌套在了另一个runat="server"的form标签里面。删除其中之一即可。

3.第三种

        如果我们在每次回发时都重新定义/实例化控件或命令,其各自或相关的事件就会很折腾。一个简单的例子就是在每次页面加载(包括回发)时重新绑定DataGrid。因为,重新绑定将导致Grid的所有控件的ID都更新,进而使得在触发DataGrid 控件事件回发时,控件的ID已变,连接不到正确控件,最终抛出错误。
        解决方法:这种情况可以简单地通过确保控件不在回发 (重新绑定) 时重新创建来解决。使用Page的IsPostback就可以轻松地处理它。如果您想要在每次回发时创建控件,则必须确保它的ID不会改变。
protectedvoidPage_Load(object sender,EventArgs e)
{
    if(!Page.IsPostback)
    {
        // Create controls
        // Bind Grid
    }
}

4.结论


 
        正如错误提示所说,最简单直接的解决方案就是在Page或Web.config中添加enableEventValidation ="false",但不推荐这么做。最好基于实际情况找出根本原因并采取相应解决方案。
 
 
原文地址:https://www.cnblogs.com/moonache/p/5422564.html