1. 程式人生 > >.NET框架學習:淺談ASP.NET的Postback

.NET框架學習:淺談ASP.NET的Postback

說道ASP.NET的Postback,就得說Web Page的生命週期,但是Web Page的生命週期卻不是三言兩語就能夠說得清楚的,所以在這裡單純站的程式設計的角度,撇開Web Page 的生命週期淺談Postback。

我們知道,無論是ASP.NET1.x,2.0,甚至是以後的版本,ASP.NET最終Render到Client端通過瀏覽器瀏覽的都是一樣:一個單純的HTML。Client通過Submit Form的方式將填入Form的資料提交給Server進行處理。我們現在來看看ASP.NET整個Postback程式處理的過程。

首先我們通過一個Sample來看ASP.NET如何處理一個通過Click一個Button引起的Postback。下面是Web Page的HTML:

<%@ Page Language="C#" AutoEventWireup="true" CodeFile="Default.aspx.cs" Inherits="_Default"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
    
<title
>Test Page</title>
</head>
<body>
    
<form id="form1" runat="server">
        
<div>
            
<asp:Label runat="server" ID="LabelMessage" ForeColor="red"></asp:Label>
        
</div>
        
<div>
            
<asp:Button runat="server" ID="Button1" Text
="Button1" OnClick="Button1_Click" OnCommand="Button_Command"     CommandArgument="Button1"/>
            
<asp:Button runat="server" ID="Button2" Text="Button2" OnClick="Button2_Click" OnCommand="Button_Command"    CommandArgument="Button2" UseSubmitBehavior="false"/>
            
<asp:Button runat="server" ID="Button3" Text="Button3" OnClick="Button3_Click" OnCommand="Button_Command"    CommandArgument="Button3" UseSubmitBehavior="false"/>
        
</div>
    
</form>
</body>
</html>

很簡單,定義了3個Button,分別註冊了他們的兩個Event:Click和Command。3個Button的Command Event Hander是一樣的:Button_Command,通過指定的CommandArgument來讓Event Handler判斷到底是哪個Button觸發了Command  Event。

下面是Code Behind:

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
{  

    
protectedvoid Page_Load(object sender, EventArgs e)
    
{
       
    }

    
protectedvoid Button1_Click(object sender, EventArgs e)
    
{
        
string message =string.Format("The {0} event of {1} is fired""Click""Button1");
        
this.LabelMessage.Text = message;
    }

    
protectedvoid Button2_Click(object sender, EventArgs e)
    
{
        
string message =string.Format("The {0} event of {1} is fired""Click""Button2");
        
this.LabelMessage.Text = message;
    }

    
protectedvoid Button3_Click(object sender, EventArgs e)
    
{
        
string message =string.Format("The {0} event of {1} is fired""Click""Button3");
        
this.LabelMessage.Text = message;
    }


    
protectedvoid Button_Command(object sender, CommandEventArgs e)
    
{
        
string message =string.Format("The {0} event of {1} is fired""Command", e.CommandArgument);
        
this.LabelMessage.Text +=""+ message;
    }

}

我們來執行這個Page,並Click某個按鈕(比如Button2):


我們通過最上方的Message可以看出,Button2的Click Event和Command先後觸發。

這篇Blog的主旨就是從方法呼叫的角度講述整個程式執行的過程:從HTML 被Render到Client端,到使用者Click某個按鈕,輸入被Postback到Server端,並觸發兩個Event,執行Event Handler打印出相關的Message。

首先我們來看看ASP.NET設計的Page Render到Client端的HTML是什麼樣子:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
    
<head>
        
<title>
            Test Page
        
</title>
    
</head>
    
<body>
        
<form name="form1" method="post" action="Default.aspx" id="form1">
            
<div>
                
<input type="hidden" name="__EVENTTARGET" id="__EVENTTARGET" value=""/>
                
<input type="hidden" name="__EVENTARGUMENT" id="__EVENTARGUMENT" value=""/>
                
<input type="hidden" name="__VIEWSTATE" id="__VIEWSTATE" value="/wEPDwUKMTA0NDQ2OTE5OWRk281L4eAk7iZT10hzg+BeOyoUWBQ="/>
            
</div>

<script type="text/javascript">
                
<!--
var theForm = document.forms['form1'];
if (!theForm) {
    theForm 
= document.form1;
}

function __doPostBack(eventTarget, eventArgument) {
    
if (!theForm.onsubmit || (theForm.onsubmit() !=false)) {
        theForm.__EVENTTARGET.value 
= eventTarget;
        theForm.__EVENTARGUMENT.value 
= eventArgument;
        theForm.submit();
    }

}

// -->
</script>

<div>
<span id="LabelMessage" style="color:Red;"></span>
</div>
<div>
    
<input type="submit" name="Button1" value="Button1" id="Button1"/>
    
<input type="button" name="Button2" value="Button2" onclick="javascript:__doPostBack('Button2','')" id="Button2"/>
    
<input type="button" name="Button3" value="Button3" onclick="javascript:__doPostBack('Button3','')" id="Button3"/>
</div>
</form>
</body>
</html>

上面的HTMLBody部分大體包括3個部分:

1.   定義了3個hidden field:

<input type="hidden" name="__EVENTTARGET" id="__EVENTTARGET" value=""/>                
<input type="hidden" name="__EVENTARGUMENT" id="__EVENTARGUMENT" value=""/>
<input type="hidden" name="__VIEWSTATE" id="__VIEWSTATE" value="/wEPDwUKMTA0NDQ2OTE5OWRk281L4eAk7iZT10hzg+BeOyoUWBQ="/>

從他們的命名可以看出他們分別代表的意思:__EVENTTARGET代表觸發Event的Control的Unique name;__EVENTARGUMENT代表為Event Handler定義的額外的引數;__VIEWSTATE:代表的是Viewstate。

2.   一段script:

<script type="text/javascript">
                
<!--
var theForm = document.forms['form1'];
if (!theForm) {
    theForm 
= document.form1;
}

function __doPostBack(eventTarget, eventArgument) {
    
if (!theForm.onsubmit || (theForm.onsubmit() !=false)) {
        theForm.__EVENTTARGET.value 
= eventTarget;
        theForm.__EVENTARGUMENT.value 
= eventArgument;
        theForm.submit();
    }

}

// -->
</script>
定義了一個__doPostBack function完成Postback的操作,該function只有區區3行程式碼,前兩行通過引數對上面定義的兩個hidden field賦值,然後向Server端提交表單。

3.   一段HTML對應通過ASP.NET定義的Web Control。 

<div>
<span id="LabelMessage" style="color:Red;"></span>
</div>
<div>
    
<input type="submit" name="Button1" value="Button1" id="Button1"/>
    
<input type="button" name="Button2" value="Button2" onclick="javascript:__doPostBack('Button2','')" id="Button2"/>
    
<input type="button" name="Button3" value="Button3" onclick="javascript:__doPostBack('Button3','')" id="Button3"/>
div>

我們定義的3個Button被轉化成3個能向Server端提交表單的<input > Tag, 但是他們提交表的方式卻不一樣,第一個以<input type="submit">的方式提交,後面兩個通過呼叫javascript的方式提交表單(<input type="button">)。對於一個System.Web.UI.WebControls.Button,預設採用第一種提交方式,但是我們通過設定UseSubmitBehavior屬性(這個屬性時ASP.NET 2.0新加的,1x沒有相應的設定),改變其表單提交的行為。

當用戶Click Button2的時候,呼叫__doPostBack,並傳入兩個引數:一個代表出發Event的物件的Unique name,也就是Button2的名稱,另一個描述Event的額外資訊的引數,這裡不需要,所以這裡是空字串。在__doPostBack中把這兩個引數賦值給兩個Hidden Field:__EVENTTARGET,__EVENTARGUMENT。然後向Server端提交表單,完成Postback。

然後我們來看看Server如何處理這個Postback,關於Web Page的生命週期在這裡就不詳細介紹了。Server端通過__EVENTTARGET這個hidden field的值找到對應的Server端的Control,通過Reflection確定該Control是否實現了System.Web.UI.IPostBackEventHandler Interface。如果該Control確實實現了該Interface,那麼呼叫Page的RaisePostBackEvent方法,這是一個Virtual的方法,可以被Override。我們來看該方法的定義。

[EditorBrowsable(EditorBrowsableState.Advanced)]
protectedvirtualvoid RaisePostBackEvent(IPostBackEventHandler sourceControl, string eventArgument)
{
    sourceControl.RaisePostBackEvent(eventArgument);
}

我們可以看到該方法直接呼叫該sourceControl的RaisePostBackEvent,並傳入一個eventArgument引數,在這個例子中sourceControl就是__EVENTTARGET對應的Web Control:Button2,eventArgument就是__EVENTTARGET對應的值:一個空字串。Button2的型別是System.Web.UI.WebControls.Button。我們來看看System.Web.UI.WebControls.Button中的方法是如何定義的:

protectedvirtualvoid RaisePostBackEvent(string eventArgument)
{
    
base.ValidateEvent(this.UniqueID, eventArgument);
    
if (this.CausesValidation)
    
{
        
this.Page.Validate(this.ValidationGroup);
    }

    
this.OnClick(EventArgs.Empty);
    
this.OnCommand(new CommandEventArgs(this.CommandName, this.CommandArgument));
}

這個方法也很簡單,先進行Validation,然後先後出發兩個Event:OnClick 和OnCommand,隨後呼叫對應的Event handler,這和我們的輸出結果是吻合的。

這基本上就是整個Postback的整個程式執行的過程,現在我們對我們的Page作一些小的有趣的改動,來驗證一下:

Client端和Server端進行互動的途徑就是提交表單(Form Submitting),而我們現在有兩種方式來提交表單:通過<input type="submit">控制元件;通過呼叫javascript:__doPostBack。基於這一點我們在Html中加了下面一段javascript: 

<script type="text/javascript">
    
function postback()
    

相關推薦

.NET框架學習ASP.NET的Postback

說道ASP.NET的Postback,就得說Web Page的生命週期,但是Web Page的生命週期卻不是三言兩語就能夠說得清楚的,所以在這裡單純站的程式設計的角度,撇開Web Page 的生命週期淺談Postback。 我們知道,無論是ASP.NET1.x,2.0,甚至是以後的版本,ASP.NET最終

【APS.NET 框架系列】ASP.NET 框架

處理請求 splay bapi tps cat 底層 show 一個 優化 本篇文章稍微偏原理且底層,有一定難度和且比較晦澀。 本篇文章主要是從廣度上概括一下,具體的更細粒度的,會在後續的文章中,結合具體的Demo實例分析。 一 .NET框架概述

ASP.NET框架

本篇文章更適合具有一定開發經驗,一定功底,且對底層程式碼有所研究的朋友!!! 本篇文章稍微偏原理且底層,有一定難度和且比較晦澀,文章粒度稍微粗些,更細粒度的,會在後續的文章中,結合具體的Demo例項分析。感興趣的朋友,可以先收藏。 一 .NET框架概述 1.作用:提

Java學習筆記——數據結構與Java集合框架(第一篇、List)

技術分享 emp 鏈表 adc 下標 -c nod nal integer 橫看成嶺側成峰,遠近高低各不同。不識廬山真面目,只緣身在此山中。               ——蘇軾 這一塊兒學的是雲裏霧裏,咱們先從簡單的入手。逐漸的撥開迷霧見太陽。本次先做List集合的三

ASP.NET MVC系列】MVC

後端 nbsp 文獻 ats 路勁 onf 將在 cot get 描述 本篇文章主要概述ASP.NET MVC,具體包括如下內容: 1.MVC模式概述 2.WebForm概述 3.WebForm與MVC區別 4.ASP.NET MVC發展歷程 5.運用程序結構 6.ASP.

ASP.NET MVC系列】表單和HTML輔助方法

繼承 好的 內容 概述 調用 復制 畫圖 models pac 【01】淺談Google Chrome瀏覽器(理論篇) 【02】淺談Google Chrome瀏覽器(操作篇)(上) 【03】淺談Google Chrome瀏覽器(操作篇)(下) 【04】淺談AS

ASP.NET配置文件加密

info provider 管理員 cti 打開 默認 命令 nec spa 在剛剛完成的一個ASP.NET項目中,遇到了這麽一個問題,項目部署到生產環境中時,領導要求項目中的配置文件(如web.config,app.config)中不能出現敏感字符,如:數據庫連接,等等。

萬樹IT:ASP.NET和Web伺服器

如何使用Silverlight 2的Beta1版本建造一個簡單的Digg客戶端應用。教程旨在按順序閱讀,幫著解釋Silverlight的一些核心程式設計概念。 使用 VS 2008 建立一個新的Silverlight 應用我們來開始我們的Digg應用的開發,先選擇Visual Studio 20

湯澄深度學習

1.關於訓練神經網路 1.1訓練神經網路是深度學習中最難的部分 先建立數學模型。需要一個超級大資料集,例如大量機場和出發日期的組合 ;需要量的計算能力。 1.2訓練過程 ·遍歷整個資料集 ·建立一個代價函式(Cost function) ·展示模型輸出與實際之間

小白學《神經網路與深度學習》筆記之一-計算機的潛意識神經網路-從神經元到深度學習

神經網路是一門重要的機器學習技術。它是目前最為火熱的研究方向--深度學習的基礎。學習神經網路不僅可以讓你掌握一門強大的機器學習方法,同時也可以更好地幫助你理解深度學習技術。 本文以一種簡單的,循序的方式講解神經網路。適合對神經網路瞭解不多的同學。本文對閱讀沒有一定的前提要

周志華深度學習

我們都知道直接掀起人工智慧熱潮的最重要的技術之一,就是深度學習技術。今天,其實深度學習已經有各種各樣的應用,到處都是它,不管影象也好,視訊也好,聲音自然語言處理等等。那麼我們問一個問題,什麼是深度學習? 深度學習的理論基礎尚不清楚 我想大多數人的答案,就是深度學習差不多就等於深度神經網路。有

Asp.net 執行機制

一、Asp.net 執行機制概述1.使用Asp.net 進行動態Web開發,編寫好Web應用程式,即動態頁面,並部署到Web伺服器,如IIS中;2.客戶端在瀏覽器輸入地址,請求相應的動態頁面;3.Web 伺服器根據客戶端的請求,對Web應用程式進行編譯或解釋,並生成HTML流

ASP.NET之旅--Asp.net的執行機制(二)

      上節中我們從Http請求在Asp.net中的執行過程進行了分析,但是對於真正核心的東西我們並沒有說明,那接下來我們將問題上拋,從底層類和物件的建立層面上來看Asp.net的執行機制。 三、Asp.net底層執行機制    1、理解HTTP.SYS      

ASP.NET之旅--Asp.net執行機制(一)

       很多Asp.net開發人員都有過Asp的背景,以至於我們開發程式的時候總是停留在“頁面”層次思考,也就是說我們常常會只考慮我們現在所做的系統是要完成什麼功能,是要做問卷調查網站還是個人網站,而很少在“請求級”思考,思考能不能通過編碼的方式來操作一個Http請

ASP.NET配置檔案加密

在剛剛完成的一個ASP.NET專案中,遇到了這麼一個問題,專案部署到生產環境中時,領導要求專案中的配置檔案(如web.config,app.config)中不能出現敏感字元,如:資料庫連線,等等。第一個想到的方法是,寫一個加密解密演算法,將這些配置檔案中的值以密文的方式存到c

ASP.NET Core中IOC與DI的理解和使用

說起IOC和DI,使用過ASP.NET Core的人對這兩個概念一定不陌生,早前,自己也有嘗試過去了解這兩個東西,但是一直覺得有點很難去理解,總覺得對其還是模糊不清,所以,趁著今天有空,就去把兩個概念捋清楚,並將學習過程的知識點記錄下來。  一、IOC和DI的理解 1.1 什麼是IOC?

ASP.NET Core中的DI

# DI的一些事 傳送門[馬丁大叔的文章](https://martinfowler.com/articles/injection.html#InversionOfControl) ## 什麼是依賴注入(DI: Dependency Injection)?     依賴注入(DI)是一種面向物件的軟體

養成良好的學習習慣-學習方法(2)

成功最有效的方法是想有經驗的人學習成功最有效的方法是想有經驗的人學習!借鑒成功的人的態度和習慣。你可以讓你在任何想達到的目標表提高成功率!1、學習不專心。上課期間少幹別的。上課保持最大化的輸入,討論自己把知識最大化的輸出。課下把知識最大化會化的輸出。2、分組學習,找1-2個同伴,共同學習。今天上午學一個點,共

養成良好的學習習慣-學習方法(1)

養成 學習習慣 良好的 淺談學習方法(1) 1.老男孩教育要培訓什麽? 思想技術 知識 2.養成良好的學習習慣和聽課習慣 1)帶一支筆和本,記錄老師講解的內容 2 總結時 ,記錄關鍵的信息,抓重點 3) 聽課習慣:調動所有感官學習 眼睛看、勤動手(

Spring.Net框架配置Spring.Net框架環境

存在 示例代碼 release 特定 pan 找不到文件 anim 新的 動物 一、下載DLL文件 去Spring的官方網站下載並解壓,然後直接添加dll文件的引用就可以了。在上一篇文章中,已經介紹過Spring.Net框架中需要使用到的dll文件。這些程序集文件位於Spr