学习AJAX Toolskit之解决故障:RegisterDataItem can only be called during an async postback.

 

学习AJAX Toolskit之解决故障:RegisterDataItem can only be called during an async postback.

当你使用AjaxControlToolkit的ajaxToolkit:PopupControlExtender 控件时,如果弹出框中有Button时,经常会遇到上面的错误。

下面是Google上得到的有关此问题的讨论网页:
http://forums.asp.net/p/1038571/1464448.aspx

ncipollina

I get this error message when I attempt to call the PopupExtender's Commit function from a Button's Click event.  It does not give this error message when called from a Calendar's SelectedItemChanged event.  I have written two user controls, one that has a Button which is to apply the results of the popup control to my textbox, and one that uses a calendar to apply the results to the textbox.  The funny thing is, I have an imagebutton on the calendar control, to cancel the popup.  It also throws the exception.  Can a button not be used to Commit the the PopupExtender?

实际上,这个问题,Microsoft公司的David Anson 作出了正确的答复:

Try setting UseSubmitBehavior=false for the Button - if that doesn't help, please reply with a complete, simple, self-contained sample page that demonstrates the problem so that we can investigate the specific behavior you're seeing. Thank you!

下面是我做的测试网页,以重现错误:

Default.aspx

<%@ Page Language="C#" AutoEventWireup="true" CodeFile="Default.aspx.cs" Inherits="_Default" %>

<%@ Register

Assembly="AjaxControlToolkit"

Namespace="AjaxControlToolkit"

TagPrefix="ajaxToolkit" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">

<html xmlns="http://www.w3.org/1999/xhtml">

<head runat="server">

<title>Untitled Page</title>

</head>

<body>

<form id="form1" runat="server">

<ajaxToolkit:ToolkitScriptManager ID="ScriptManager1" runat="server" /> &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;

<asp:TextBox ID="TextBox1" runat="server"></asp:TextBox>

<asp:Button ID="Button1" runat="server" OnClick="Button1_Click" Text="Button" />

<ajaxToolkit:ModalPopupExtender ID="ModalPopupExtender1" runat="server" PopupControlID="Panel1" TargetControlID="Button1">

</ajaxToolkit:ModalPopupExtender>

<asp:Panel ID="Panel1" runat="server" Height="88px" Width="190px">

&nbsp; &nbsp;

<asp:Button ID="btnOK" runat="server" EnableTheming="False" OnClick="btnOK_Click"

Text="OK" />

<asp:Button ID="btnno" runat="server" Text="No" />

<asp:TextBox ID="TextBox2" runat="server"></asp:TextBox></asp:Panel>

<ajaxToolkit:PopupControlExtender ID="PopupControlExtender1" runat="server" OffsetX="50"

OffsetY="50" PopupControlID="Panel2" Position="Right" TargetControlID="TextBox1">

</ajaxToolkit:PopupControlExtender>

&nbsp;

<asp:Panel ID="Panel2" runat="server" Height="50px" Width="125px">

<asp:UpdatePanel ID="UpdatePanel1" runat="server">

<ContentTemplate>

<asp:TextBox ID="TextBox3" runat="server"></asp:TextBox>

<asp:Button ID="btnInUP" runat="server" OnClick="btnInUP_Click" Text="Button" />&nbsp;&nbsp;

</ContentTemplate>

</asp:UpdatePanel>

</asp:Panel>

</form>

</body>

</html>

Default.aspx.cs

using System;

using System.Data;

using System.Configuration;

using System.Web;

using System.Web.Security;

using System.Web.UI;

using System.Web.UI.WebControls;

using System.Web.UI.WebControls.WebParts;

using System.Web.UI.HtmlControls;

public partial class _Default : System.Web.UI.Page

{

protected void Page_Load(object sender, EventArgs e)

{

}

protected void Button1_Click(object sender, EventArgs e)

{

this.ModalPopupExtender1.Show();

}

protected void btnOK_Click(object sender, EventArgs e)

{

TextBox1.Text = TextBox2.Text + "aaaaaaaaa";

}

protected void btnInUP_Click(object sender, EventArgs e)

{

// TextBox1.Text = TextBox3.Text;//OK

PopupControlExtender1.Commit(TextBox3.Text); //会产生错误

}

}

按David Anson的方法修正:

学习AJAX Toolskit之解决故障:RegisterDataItem can only be called during an async postback.

则一切正常。

MSDN关于此行为的描述:

ms-help://MS.VSCC.v80/MS.MSDN.v80/MS.VisualStudio.v80.chs/dv_aspnetcon/html/66b3ce28-3b93-4f0a-951f-42fb5bb5fddf.htm

按钮回发行为

当用户单击按钮控件时,该页回发到服务器。默认情况下,该页回发到其本身,在这里重新生成相同的页面并处理该页上控件的事件处理程序。

可以配置按钮以将当前页面回发到另一页面。这对于创建多页窗体可能非常有用。有关详细信息,请参见 ASP.NET 网页中的跨页发送

默认情况下,Button 控件使用 HTML POST 操作提交页面。LinkButtonImageButton 控件不能直接支持 HTML POST 操作。因此,使用这些按钮时,它们将客户端脚本添加到页面以允许控件以编程方式提交页面。(因此 LinkButtonImageButton 控件要求在浏览器上启用客户端脚本。)

在某些情况下,您可能希望 Button 控件也使用客户端脚本执行回发。这在希望以编程方式操作回发(如将回发附加到页面上的其他元素)时可能非常有用。可以将 Button 控件的 UseSubmitBehavior 属性设置为 true 以使 Button 控件使用基于客户端脚本的回发。

Collapse 图像处理 Button 控件的客户端事件

Button 控件既可以引发服务器事件,也可以引发客户端事件。服务器事件在回发后发生,且这些事件在为页面编写的服务器端代码中处理。客户端事件在客户端脚本(通常为 ECMAScript (JavaScript))中处理,并在提交页面前引发。通过向 ASP.NET 按钮控件添加客户端事件,可以执行任务(如在提交页面前显示确认对话框以及可能取消提交)。有关详细信息,请参见 ASP.NET 网页中的客户端脚本如何:响应客户端脚本中的 Button Web 服务器控件事件

Collapse 图像数据控件中的按钮

Button Web 服务器控件常用于数据控件(如 DataList、GridView 和 Repeater 列表控件)中。如果是这种情况,则对按钮控件的事件的响应通常应与在窗体上以独占方式使用按钮控件时不同。当用户单击数据控件中的一个按钮时,事件消息发送到该数据控件,该消息在数据控件中引发一个特定于该数据控件的事件。例如,在 DataList 控件中,一个按钮可能引发 DataList 控件的 ItemCommand 事件而不是引发 Button 控件的 Click 事件。

因为 List Web 服务器控件可以包含许多不同的按钮,所以可以设置按钮的 CommandArgument 属性以指定一个作为事件的一部分传递的值。然后,可以测试该参数以确定哪个按钮被单击。

结论

当使用AJAX的Update Panel空间当作Popup面板时,务必将其内部的所有server端控件不要使用基于客户端脚本的回发。

MSDN文档中的那段文字,似乎写错了,按测试的结果,应该将true改为false是:

….可以将 Button 控件的 UseSubmitBehavior 属性设置为 false以使 Button 控件使用基于客户端脚本的回发。

关于HTTP GET和HTTP POST

HTTP-GET和HTTP-POST是使用HTTP的标准协议动词,用于编码和传送变量名/变量值对参数,并且使用相关的请求语义。每个HTTP- GET和HTTP-POST都由一系列HTTP请求头组成,这些请求头定义了客户端从服务器请求了什么,而响应则是由一系列HTTP应答头和应答数据组成,如果请求成功则返回应答。

HTTP-GET以使用MIME类型application/x-www-form- urlencoded的urlencoded文本的格式传递参数。Urlencoding是一种字符编码,保证被传送的参数由遵循规范的文本组成,例如一个空格的编码是"%20"。附加参数还能被认为是一个查询字符串。

  与HTTP-GET类似,HTTP-POST参数也是被URL编码的。然而,变量名/变量值不作为URL的一部分被传送,而是放在实际的HTTP请求消息内部被传送。

GET与POST的区别在于:(对于CGI)

如果以GET方式传输,所带参数附加在CGI程式的URL后直接传给server,并可从server端的QUERY_STRING这个环境变量中读取;

如果以POST方式传输,则参数会被打包在数据报中传送给server,并可从CONTENT_LENGTH这个环境变量中读取出来。

还有一种情况是,你用的是GET方式,但传送的参数是路径,如:

----< ahref="/cgi-bin/a.pl/usr/local/bin/pine" >CGI< /a >

----这时所传递的参数"/usr/local/bin/pine"存放在PATH_INFO这个环境变量中。环境变量的读取方式为$str=$ENV{'QUERY_STRING'};

理论上说,GET是从服务器上请求数据,POST是发送数据到服务器。事实上,GET方法是把数据参数队列(query string)加到一个URL上,值和表单是一一对应的。比如说,name=John。在队列里,值和表单用一个&符号分开,空格用+号替换,特殊的符号转换成十六进制的代码。因为这一队列在URL里边,这样队列的参数就能看得到,可以被记录下来,或更改。通常GET方法还限制字符的大小。事实上 POST方法可以没有时间限制的传递数据到服务器,用户在浏览器端是看不到这一过程的,所以POST方法比较适合用于发送一个保密的(比如信用卡号)或者比较大量的数据到服务器。

Post是允许传输大量数据的方法,而Get方法会将所要传输的数据附在网址后面,然后一起送达服务器,因此传送的数据量就会受到限制,但是执行效率却比Post方法好。

你可能感兴趣的:(async)