您所在的位置: 程序员家园 -> 家园博客 ->
 
在哪里摔倒
就在哪里自己爬起来

用户登录

查  找

最新评论

最新留言

常用网站

网易邮箱 GMAIL  

百度搜索 MSDN

霏凡软件 BT精品

影视帝国 射 手 网

电驴下载 全 库 网

友情连接

茄菲的窝 冰冰博客

枫叶飘零 玫  瑰

ACEN 云 豹 子

统  计



回发或回调参数无效
狼子 发表于 2007-1-10 19:24:00 阅读全文 | 回复(4) | 引用通告 | 编辑  asp.net查看本站使用过本标签的日志查看本站使用过本标签的用户

完整的出错信息:

回发或回调参数无效。在配置中使用 <pages enableEventValidation="true"/> 或在页面中使用 <%@ Page EnableEventValidation="true" %> 启用了事件验证。出于安全目的,此功能验证回发或回调事件的参数是否来源于最初呈现这些事件的服务器控件。如果数据有效并且是预期的,则使用 ClientScriptManager.RegisterForEventValidation 方法来注册回发或回调数据以进行验证。

出错原因有两种:

1、页面里有<form>的嵌套

2、用js动态给DropDownList控件添加了Load页面时DropDownList里面没有的ListItem

解决办法:

1、把嵌套的<form>去掉就可以了,我在做导出静态页面后的搜索时,遇过这种情况,我把<form>去掉,使用js在地址栏里提交参数了,这个方法写在这里(user1/9/archives/2006/3223.html

2、这个我不知道我上面的描述对不对,我的意思是说,如果在页面Load的时候,DropDownList有三个ListItem

<asp:ListItem>1</asp:ListItem>
<asp:ListItem>2</asp:ListItem>
<asp:ListItem>3</asp:ListItem>

这时,如果使用JavaScript给这个DropDownList再加一项

<%= this.DropDownList1.ClientID %>.options[i]=new Option("4","4");

这样就给下拉菜单加了一项:<asp:ListItem>4</asp:ListItem>了

这一项,在页面Load的时候,是没有的,就是没有写进隐藏域

<input type="hidden"
       name="__EVENTVALIDATION"
       id="__EVENTVALIDATION"
       value="/wEWBQKGg9abDQKd9sHMBgKc9s........"
/>

所以呢,在提交数据的时候,在检验数据的时候,就会发现这一项是没有的,就是没有注册的意思,是客户自己加在下拉菜单里的数据,有可能是有问题的数据,所以验证数据就不通过了

如果按照错误提示里说的,设置

<%@ Page EnableEventValidation="false" %>

你就会发现,服务器端读取不到下拉菜单的选中值了

我看了这三个东西,读的不是很懂

http://recordsome.blogsome.com/2006/05/30/aspnet-event-validation/

http://odetocode.com/Blogs/scott/archive/2006/03/20/3145.aspx

http://odetocode.com/Blogs/scott/archive/2006/03/21/3153.aspx

第一个连接是那个作者读了后面两个写的,我把后面两个也读了,后现两个很难连上,我把页面保存了,上传一份你们看:UploadFiles/2007-1/110254752.rar

我想这三个文章里面,是提供了一种使用代码解决这个问题的方法的,就是我测试了很多,还是解决不到

所以我就想了另一个办法,很简单的办法,因为数据是在页面Load的时候注册的,所以我就把初始数据全部写DropDownList里,在页面Load完的时候再把不要的数据删除

这样全部可能用到的项就都自动注册了,就不会出错了,我把我写的省市联动的自定义用户控件给上来:UploadFiles/2007-1/110826673.rar

这种解决方法有一个不好的地方,就是如果要用到的项是未知的,那就没有办法预先加载了,这种办法就用不上了

我遇到这种情况了的,就是(user1/9/archives/2006/3237.html)里写的那种字典表,如果我想要在用户录入的时候,让用户随便添加字典表里的内容,添加数据到字典表可以使用window.showModalDialog打开一个模式窗口添加,添加完了,数据不可以自动写回下拉菜单了

有两个问题:

1、如果使用模式窗口返回添加的数据,用JavaScript把返回的数据写入下拉菜单,这个新添加的ListItem就会因为没有注册而出错了

2、因为上面的原因,所以我没有用JavaScript添加ListItem,我加了一个小button在下拉菜单的旁边,用来刷新下拉菜单,在刷新下拉菜单的时候,如果直接用

DropDownList1.DataBind();

会报错的,详细出错信息忘了,记不起来了,我的解决办法是重新一项一项读取

private void RefrestCheckBoxList(ObjectDataSource ods, string ddlna)
    {
        //刷新CheckBoxList
        CheckBoxList mycbl = new CheckBoxList();
        mycbl = (CheckBoxList)FormView1.FindControl(ddlna);
        if (mycbl != null)
        {
            DataView dv = new DataView();
            dv = (DataView)ods.Select();
            //清空Items
            mycbl.Items.Clear();
            //添加Items
            foreach (DataRowView drv in dv)
            {
                mycbl.Items.Add(new ListItem(drv.Row["dna"].ToString(), drv.Row["dna"].ToString()));
            }
        }
    }

所以,真正的解决办法,还是在上面的那三个读不大懂的帖子里,我现在是解决了一半

Re:回发或回调参数无效
mountain315发表评论于2007-3-24 12:05:00 个人主页 | 引用 | 返回 | 删除 | 回复

从百度查到下面的方法,还没有测试过,先记下:

3.使用RegisterForEventValidation注册客户端控件的值。

可能还有别的方法,不过我没有注意到。我是参考的第三种方法实现的。

解决方法:在Page_Load之前加入如下代码

 protected override void Render(HtmlTextWriter writer)
    {

        ClientScript.RegisterForEventValidation(DropDownList1.UniqueID, "argument");
        base.Render(writer);
    }

DropDownList1就是你要使用客户端脚本动态增加内容的控件,而argument就是你要加入的值。例如本来DropDownList1是空的,你用脚本为它增加了“中国”,“美国”等值,这里的代码就改成

ClientScript.RegisterForEventValidation(DropDownList1.UniqueID, "中国");

ClientScript.RegisterForEventValidation(DropDownList1.UniqueID, "美国");

原理:就是因为vs2005的这个数据验证问题了,"在asp.net render DropDownList 时,会遍历DropDownList的item,并记录所有可能的postback的值,计算的结果会被保存在page中,

<input type="hidden"
       name="__EVENTVALIDATION"
       id="__EVENTVALIDATION"
       value="/wEWBQKGg9abDQKd9sHMBgKc9s…….."
/>
这个过程发生在control的Render()方法中
当页面postback时,ASP.NET会根据这个隐藏值检查postback values,如果找不到对应信息,就会报错"(引自http://recordsome.blogsome.com/2006/05/

所以我们重写Render,将由脚本加入控件中的值加入到隐藏值中,就不会出现找不到相应信息的错误了。

Re:回发或回调参数无效
mountain315发表评论于2007-4-2 20:43:00 个人主页 | 引用 | 返回 | 删除 | 回复

这个问题在这里,我在微软中文社区得到了解决,整个贴子我记录在这里了:user1/9/archives/2007/3584.html

使用代码注册,是这种Render方法:

protected override void Render(System.Web.UI.HtmlTextWriter writer)
    {
        ClientScript.RegisterForEventValidation(DropDownList1.UniqueID, "Canada");
        ClientScript.RegisterForEventValidation(DropDownList1.UniqueID, "Mexico");
        ClientScript.RegisterForEventValidation(DropDownList1.UniqueID, "United States");
        base.Render(writer);
    }

使用这个方法注册后,取数据时需要使用Request.Form来取

Re:回发或回调参数无效
奔夜的咒发表评论于2007-4-9 16:09:00 个人主页 | 引用 | 返回 | 删除 | 回复
我想请问一下,页面中dropdownlist1、dropdownlist2是联动的,其ListItem是动态的,以数组形式生成,其格式为:var Arrays =  new Array([0,'aaa,3], [0,'bbbbb',4]...)(注:数据库字段——ParentID,Name,ID),怎么添加ClientScript.RegisterForEventValidation的值呀????谢
Re:回发或回调参数无效
mountain315发表评论于2007-4-12 13:36:00 个人主页 | 引用 | 返回 | 删除 | 回复

你的数组里的内容是程序在编写时就可以预知的吗?比如说是在数据库里的,可以直接读取数据库的,比如说像省市一样,是已经知道的内容

如果是这样的,你可以使用Render方法注册,使用这个方法后,取数据时使用Request.Form("DropDownList2")取值,下面这一段我没有放在vs.net2005里测试过,我想这样应该可以把每一项注册进去:

protected override void Render(System.Web.UI.HtmlTextWriter writer)
    {
        //读取数据库
        //获取连接字符串
        string connectionString = ConfigurationManager.ConnectionStrings["web.config里记录连接字串的节点名"].ConnectionString;
        //创建并设置SqlConnection
        SqlConnection dbConnection = new SqlConnection(connectionString);
        string value="";
        queryString = "select value字段的字段名 from 表名";
        try
        {
            //取数据
            dbConnection.Open();
            SqlCommand MyCommand = new SqlCommand(queryString, dbConnection);
            SqlDataReader dr = MyCommand.ExecuteReader();
            DataRow row;
            //循环写数据
            while (dr.Read())
            {
                value = dr["value字段的字段名"].ToString();
                ClientScript.RegisterForEventValidation(DropDownList1.UniqueID, value);
            }
        }
        catch (Exception)
        {
            //
        }
        finally
        {
            dbConnection.Close();
        }
        base.Render(writer);
    }

这个方法只是注册,联动还是要通过js来做,就是使用了这个方法注册后,js修改的值,只要是这个方法里注册过的值,就不会再报错了

发表评论:

    昵称:
    密码:
    主页:
    标题:
Powered by Oblog.