2008年7月27日 星期日

ASP.NET無接縫傳值的撰寫模式

問題說明:
所謂ASP.NET的『無接縫傳值』,是指在撰寫網頁間的傳值時,不使用queryString或Session來傳值,而是利用元件的PostBackUrl和Page的PreviousPage來完成網頁間的傳值。一般說來,queryString的方式容易使得網頁的運作參數暴露在瀏覽器的網址列,而遭有心人士利用;而session傳值的方式,容易在使用者同時開啟多個網頁時,產生資料錯置的嚴重錯誤。所以說網頁間的傳值最少必須是使用『無接縫傳值』模式,網站系統的安全性才能獲得基本的保障。

『無接縫傳值』簡易撰寫模式:
一般Asp.Net的程式設計師,大都可以輕易的完成。
首先,在父頁上部署一個具有PostBackUrl Method的元件,並設定此元件的PostBackUrl值。
例如:ImageButton1.PostBackUrl="Page2.aspx";
然後,在Page2.aspx的Page_Load event中接收傳值,語法如下:
protected void Page_Load(object sender, EventArgs e)
{
string postedValue=string.Empty();
if (Page.PreviousPage != null && Page.PreviousPage.IsCrossPagePostBack == true)
postedValue=((TextBox)Page.PreviousPage.FindControl("TextBox1")).Text;
.
.
.
}
如果你使用了MasterPage的機制,請將FindControl的方法,修改如下:
((TextBox)PreviousPage.Master.FindControl("ContentPlaceHolder1").FindControl("TextBox1")).Text;//TextBox1是主頁的控制項ID,也是傳值的控制項

『無接縫傳值』進階整合撰寫模式:
整合AjaxToolKit的HoverMenuExtender控制項,由GridView的子選單中,傳出選取資料列的Key值,並將
PostBackUrl的頁面開啟在新的window。也就是說,當使用者點選選單上的選項後,會開啟新視窗,而新視窗必須接到傳值才能顯示詳細資料,不接受QueryString或Session的方式傳值;當新視窗無法獲得Key時會自動於顯示錯誤說明後關閉視窗。
這個做法包含下列兩個問題:
1.要如何讀取GridView中HoverMenuExtender控制項LinkButton的CommandArgument
2.要如何讓PostBackUrl的網頁在新視窗開啟
如果解決了這兩個問題,再配合基本撰寫模式,網頁間的無縫傳值就可以正確運作了。

我的做法:
1.宣告LinkButton的相關屬性,例如:
<asp:LinkButton ID="lnBtnEdit" runat="server" OnCommand="lnBtnEdit_Click" PostBackUrl="~/Admin/eArticleEdit.aspx" OnClientClick="var scriptName=document.forms[0].action;window.document.forms[0].target='_blank';setTimeout(function(){window.document.forms[0].target='';document.forms[0].action=scriptName;}, 500);" CommandArgument='<%# Bind("articleId") %>'>《編修文章》</asp:LinkButton>

 有關OnClientClick和CommandArgument也可以在GridView1_RowDataBound(object sender, GridViewRowEventArgs e)中完成設定。

2.完成lnBtnEdit_Click的事件程式碼:
protected void lnBtnEdit_Click(Object sender, CommandEventArgs e)
{
HiddenField hf = (HiddenField)Page.Master.FindControl("postbackHF");
hf.Value = e.CommandArgument.ToString();
}


3.在Page2.aspx的Page_Load event中接收傳值。

以上作法就可以完成,ASP.NET無接縫傳值,讓編修資料的頁面,在新的視窗中開起。
接著問題來了,當編修資料頁面完成存檔後,可能需要讓父頁重新Binding資料,該如何做呢~?
請看下回分解!