下午到客戶測試區加班,年輕同事問了一個關於ASP.NET Web Form跨網頁導向的問題,進一步討論到HyperLink與LinkButton控制項的差異,趁睡前趕緊筆記。
環境準備
1.打開Visual Studio,新增一個Web Form網站專案(Ctrl + Shift + N)
2.在新的專案內新增兩個新項目(Ctrl + Shift + A): WebForm1.aspx 及WebForm2.aspx。
3.打開WebForm1.aspx程式碼,在form區塊內輸入導向到WebForm2.aspx的兩段程式碼(Hyperlink x LinkButton = NavigateUrl x PostBackUrl)
<form id="form1" runat="server">
<div>
<asp:HyperLink NavigateUrl="~/WebForm2.aspx" runat="server" Text="超連結" />
<hr />
<asp:LinkButton Text="連結按鈕" runat="server" PostBackUrl="~/WebForm2.aspx" />
</div>
</form>
4.執行WebForm1.aspx
超連結和連結按鈕的測試環境準備好了,來實驗去!
- Http方法差異
- 存取原始網頁控制項
- LinkButton的Click
Http方法差異
1.為了觀察Http Method,我們簡單用開發人員工具來紀錄。
在瀏覽器按下F12,啟動開發人員工具,點到網路的頁簽,接著按下綠色的按鈕,最後依序點選超連結及連結按鈕。
2.超連結,如同預期的是使用Http GET方法
Request: GET /WebForm2.aspx HTTP/1.1
不過,沒有內文喔!直接從Method看出要Request哪一個網頁。
3.而連結按鈕(LinkButton)則是HTTP POST方法
Request: POST /WebForm2.aspx HTTP/1.1,但有內文長度568B
點開要求本文內,嗯,果然內含了VIEWSTATE。
寄明信片(Get) vs 寄有信封的信(Post) ,雖然也是Http Method,但使用上和REST架構不太相同。
存取原始網頁控制項
除了Http方法上的差異外,使用LinkButton時還有一個特別的地方,透過HTTP POST帶入的viewstate以及保存機制,我們還可以在webform2網頁中使用PreviousPage存物件存取webform1上的控制項值。來試試!
1.在webform1.aspx新增一個textbox,命名為txtCrossPage
<asp:TextBox id="txtCrossPage" runat="server" />
2.在webform2.aspx.cs新增以下內容,若為PreviousPage非null,就顯示IsCrossPagePostBack值以及webform1.aspx裡頭txtCrossPage.text()的值
protected void Page_Load(object sender, EventArgs e)
{
Response.Write($"Page.IsPostBack: {Page.IsPostBack}</br>");
if (PreviousPage != null)
{
Response.Write($"PreviousPage.IsCrossPagePostBack: {PreviousPage.IsCrossPagePostBack}</br>");
Response.Write($"value: {(PreviousPage.FindControl("txtCrossPage") as TextBox).Text} </br>"); }
}
3.執行時在文字方塊輸入我來自WebForm1,然後點選超連結按鈕到webform2.aspx
4.導向到WebForm2.aspx的結果
取到Webform1.aspx控制項的值了。
*如果是HyperLink,PreviousPage則會為null,只顯示了Page.IsPostBack = False
LinkButton的Click
此外,LinkButton主要目的可以先Postback回Server Side,執行我們想觸發的事件方法後,我們自己再以程式方式處理網頁導向。
1.首先開始WebForm1.aspx加入一段LinkButton,並且設定OnClick委派事件給LinkButton1_Click方法。
<hr />
<asp:LinkButton Text="連結按鈕With(OnClick)" runat="server" OnClick="LinkButton1_Click" />
(記得要取消postbackurl)
2.WebForm1.aspx.cs
public partial class WebForm1 : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
Debug.WriteLine("ASP.NET TRACE:", "WebForm1 page_load called.");
}
protected void LinkButton1_Click(object sender, EventArgs e)
{
Debug.WriteLine("ASP.NET TRACE:", "WebForm1 LinkButton1_Click called.");
Response.Redirect("~/WebForm2.aspx");
}
}
3.在瀏覽器按下F12,啟動開發人員工具,點到網路的頁簽,接著按下綠色的按鈕,最後點連結按鈕with(OnClick)。
4.從Visual Studio的執行輸出\偵錯(Ctrl+ Alt + O),網頁先Postback 回server side(WebForm1),依序執行page_load及LinkButton_Click
5.從網路也可以觀察到先postback回WebForm1,返回網頁後,再從Client Response.Redirect到WebForm2。
最後交易的流程就會變成:
小結:
- 單純想跨網頁導向用超連結(Hyperlink)。
- 如果有需要PostBack或是存取原網頁控制項,再考慮PostBackUrl類型的控制項(LinkButton、ImageButton、Button..)。
- LinkButton中的PostBackUrl和OnClick只能擇一,PostBackUrl優先。
- PreviousPage適用在同一應用程式區內(同網站同應用程式集區)。
參考:
What is the difference between Hyperlink control and link control in ASP.NET?