文章目錄
當你使用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" />
<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">
<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>
<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" />
</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的方法修正:
則一切正常。
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 操作提交頁面。LinkButton 和 ImageButton 控制項不能直接支援 HTML POST 操作。因此,使用這些按鈕時,它們將用戶端指令碼添加到頁面以允許控制項以編程方式提交頁面。(因此 LinkButton 和 ImageButton 控制項要求在瀏覽器上啟用用戶端指令碼。)
在某些情況下,您可能希望 Button 控制項也使用用戶端指令碼執行回傳。這在希望以編程方式操作回傳(如將回傳附加到頁面上的其他元素)時可能非常有用。可以將 Button 控制項的 UseSubmitBehavior 屬性設定為 true 以使 Button 控制項使用基於用戶端指令碼的回傳。
處理 Button 控制項的用戶端事件
Button 控制項既可以引發伺服器事件,也可以引發用戶端事件。伺服器事件在回傳後發生,且這些事件在為頁面編寫的伺服器端代碼中處理。用戶端事件在用戶端指令碼(通常為 ECMAScript (JavaScript))中處理,並在提交頁面前引發。通過向 ASP.NET 按鈕控制項添加用戶端事件,可以執行任務(如在提交頁面前顯示確認對話方塊以及可能取消提交)。有關詳細資料,請參見 ASP.NET 網頁中的用戶端指令碼和如何:響應用戶端指令碼中的 Button Web 伺服器控制項事件。
資料控制項中的按鈕
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方法好。