遇到問題: 希望點擊頁面中下拉式清單,觸發onChange事件,想在onChange事件中用到伺服器端方法(根據選中的值對頁面中的控制項進行操作,需要調用底層的一些方法)
解決辦法:
頁面中加入js 指令碼:
<script type="text/javascript">
function fnRole_OnChange(role)
{
if(role.length > 0)
{
$("#<%= hidRole.ClientID %>").val(role); //把下拉式清單選中值存到伺服器端組件隱藏欄位中,以備伺服器端調用
<%= Page.ClientScript.GetPostBackEventReference(Page,"role") %>;
}
}
</script>
在後台代碼中加入:
第一步: 該頁需要繼承介面IPostBackEventHandler
如: public partial class PopInsertUser : System.Web.UI.Page, IPostBackEventHandler
protected void Page_Load(object sender, EventArgs e)
{
ddlRole.Attributes["OnChange"] = "fnRole_OnChange(this.value);";
...........
}
第二步: 需要實現介面IPostBackEventHandler中的方法RaisePostBackEvent
public void RaisePostBackEvent(string eventArgument)
{
if ((eventArgument == "role") && (hidRole.Value.Length > 0))
{
if (this.isHideGroup(hidRole.Value)) //在isHideGroup方法中調用底層的方法
{
ListItem _nullGroup = new ListItem();
_nullGroup.Text = "未設定";
_nullGroup.Value = "";
ddlGroup.Items.Insert(0, _nullGroup);
this.ddlGroup.SelectedValue = "";
this.ddlGroup.Enabled = false;
}
else
{
ddlGroup.Items.RemoveAt(0);
this.ddlGroup.Enabled = true;
}
}
}
asp.net頁面回傳與js調用服務端事件、PostBack的原理詳解 收藏
Asp.net中服務端控制項事件是如何觸發的
Asp.net 中在用戶端觸發伺服器端事件分為兩種情況:
一. WebControls中的Button 和HtmlControls中的Type為submit的HtmlInputButton
這兩種按鈕最終到用戶端的表現形式為:<input type="submit" value="Submit">,這是Form表單的提交按鈕,點擊以後會作為參數發送到服務端,參數是這樣的:
控制項的name屬性=控制項的value值,對應上面的例子就是:Submit1= Submit。伺服器端會根據接收到的控制項的name屬性的這個key來得知是這個按鈕被點擊了,從而在服務端觸發這個按鈕的點擊事件。
二. HtmlControls 中的 Type為button的HtmlInputButton 和其它所有的控制項事件,比如LinkButton點擊,TextBox的Change事件等等:
這些事件在用戶端產生後會經過一個統一的機制發送到服務端。
1.首先asp.net頁架構會使用兩個Hidden域來存放表示是哪個控制項觸發的事件,以及事件的參數:
<!―表示觸發事件的控制項,一般是這個控制項的name -->
<input type="hidden" value="" />
<!―表示觸發事件的參數,一般是當某個控制項有兩個以上的事件時,用來區別是哪個事件 -->
<input type="hidden" value="" />
2.服務端會產生一個jscript的方法來處理所有這些事件的發送,這段代碼是:
<script language="javascript" type="text/javascript">
function __doPostBack(eventTarget, eventArgument)
{
var theform = document.WebForm2;
theform.__EVENTTARGET.value = eventTarget;
theform.__EVENTARGUMENT.value = eventArgument;
theform.submit();
}
</script>
3.每個會引發服務端事件的控制項都會在響應的用戶端事件中調用上面的代碼:
比如,HtmlControls 中的 Type為button的HtmlInputButton的點擊事件
<!―用戶端的點擊事件調用__doPostBack,eventTarget 參數為'Button2',表示是name為'Button2’控制項觸發的事件,eventArgument 為空白,表示這個Type為button的HtmlInputButton只有一個用戶端觸發的服務端事件-->
<input language="javascript" Button2','')" type="button" value="Button" />
又比如,TextBox控制項的Change事件
<!―用戶端的onchange事件調用__doPostBack,eventTarget 參數為’TextBox1’,表示是name為’TextBox1’控制項觸發的事件,而TextBox控制項只有一個用戶端觸發的服務端事件TextChanged,故伺服器就會去觸發這個TextBox的TextChanged事件->
<input type="text" TextBox1','')" language="javascript" />
4.用戶端觸發事件後調用__doPostBack方法,將表示觸發的控制項源的eventTarget 和事件參數eventArgument分別付給兩個隱藏欄位__EVENTTARGET和__EVENTARGUMENT,然後提交Form,在服務端根據__EVENTTARGET和__EVENTARGUMENT來判斷是哪個控制項的什麼事件觸發了。
第二章、 PostBack的原理
__doPostBack是一個純粹並且是非常簡單的javascript函數,大部分的頁面PostBack都是由它觸發的。注意,這裡是“大部分”,因為只有兩個Web Server Control 會自己觸發頁面的PostBack,其它的所有控制項都是通過__doPostBack函數觸發頁面的PostBack,那先來看一下這個函數的定義吧:
CODE1:
<input type="hidden" value="" />
<input type="hidden" value="" />
function __doPostBack(eventTarget, eventArgument) {
if (!theForm.onsubmit || (theForm.onsubmit() != false)) {
theForm.__EVENTTARGET.value = eventTarget;
theForm.__EVENTARGUMENT.value = eventArgument;
theForm.submit();
}
}
通過上面的代碼可以看到,__doPostBack帶有兩個參數,eventTarget是標識將要引發頁面PostBack的控制項ID,eventArgument參數提供了在引發頁面PostBack事件時所帶的額外參數。當然這個函數被函數時,這兩個參數的值將賦值給頁面的兩個隱含變數__EVENTTARGET和__EVENTARGUMENT,然後調用頁面的submit方法提交頁面表單。這就是為什麼我們可以通過Request.Form[“__EVENTTARGET”]擷取得到引發頁面PostBack的控制項ID的原因。
瞭解了__doPostBack函數後,我們可以很容易的利用它非常方便地自己觸發自訂的PostBack事件。那上面也說了,大部分的控制項都是調用
第三章 Button PostBack做法
引了頁面的PostBack,只有兩個控制項是例外,Button 和 ImageButton,正是因為它們不是通過調用__doPostBack來回傳事件,所以通過表單隱含變數__EVENTTARGET和__EVENTARGUMENT是無法擷取得到引發PostBack的Button或ImageButton的ID和參數值的,可通過下面的方式實現
1)在頁面中加如 LinkButton ,頁面就會在頁面中載入POSTBACK所需的JS
<input type="hidden" value="" />
<input type="hidden" value="" />
function __doPostBack(eventTarget, eventArgument) {
if (!theForm.onsubmit || (theForm.onsubmit() != false)) {
theForm.__EVENTTARGET.value = eventTarget;
theForm.__EVENTARGUMENT.value = eventArgument;
theForm.submit();
}
}
2)利用GetPostBackEventReference給用戶端產生__doPostBack()
如:
比如前台頁面
<asp:Button id="Button1" runat="server" Text="Button"></asp:Button>
(1)
<a href="#" onclick="document.getElementById('Button1').click()">觸發伺服器端按鈕事件</a>
(2)
利用GetPostBackEventReference給用戶端產生__doPostBack()
前台
<a href="#" onclick="<%=PostBack()%>">觸發伺服器端按鈕事件</a>
後台
protected string PostBack()
{
return this.Page.GetPostBackEventReference(this.Button1,"haha");
}
通過__EVENTARGUMENT="haha"可以判斷是不是點了那個連結的PostBack把Button1的按鈕事件這麼寫:
if(Request["__EVENTARGUMENT" ]=="haha")
{
Response.Write("這個是連結的PostBack");
}
else
{
Response.Write("這個不是連結的PostBack");
}
Bug:
問題:『使用__doPostBack會導致』
回傳或回調參數無效。在配置中使用 <pages enableEventValidation="true"/> 或在頁面中使用 <%@ Page EnableEventValidation="true" %> 啟用了事件驗證。出於安全目的,此功能驗證回傳或回調事件的參數是否來源於最初呈現這些事件的伺服器控制項。如果資料有效並且是預期的,則使用 ClientScriptManager.RegisterForEventValidation 方法來註冊回傳或回調資料以進行驗證。
問題分析及解決方案:『來源網路』
這個要具體分析。本來這個措施是asp.net2.0用來防止用戶端“欺詐”伺服器端的。例如本來輸出到用戶端的一個事件被觸發時需要回傳的命令是“__doPostback('ctl01$abc','user_1')”的,如果採取採取手段把回傳參數由 user_1 改為 user_5 了,伺服器端會重新核對輸出的是不是user_5,發現和這個頁面上一個輸出的指令碼不一致,就會產生這個異常。
但是,很多程式員寫的程式按照過去的習慣(或者按照更加進階靈活的設計例如一些Ajax組件)沒有考慮這個問題或者是忽略這個欺詐的可能性,寫的程式可能會修改參數或者修改目標控制項。
因此這樣具體問題具體分析。不太可能跟瀏覽器距離伺服器的遠近有關,應該還是編程邏輯問題。你應該對出異常的畫面以及所使用的資料進行分析。有時候,經常也需要將這個參數設定為false,放棄安全管理
本文來自CSDN部落格,轉載請標明出處:http://blog.csdn.net/lee576/archive/2008/11/30/3413930.aspx