標籤:定義 create ges bool 16px 承擔 介紹 ashx event
應用程式定義域
使用.Net建立的可執行程式*.exe,並沒有直接承載到進程當中,而是承載到應用程式定義域(AppDomain)當中。應用程式定義域是.Net引入的一個新概念,它比進程所佔用的資源要少,可以被看做是一個輕量級的進程。一個應用程式定義域可以有多個線程,一個線程也可以穿梭於多個應用程式定義域。
那為什麼會出現應用程式定義域呢?根據它的名字"域"我們可能會聯想到網域名稱,其實差不多就是這個概念了,ASP.NET通過這個應用程式定義域,主要的功能就是進行隔離.
這樣在不一個網站死掉的情況下,部署在IIS上的其他網站也不至於死掉.所有所它最重要的功能就是"隔離"
下面來簡單看看它的使用
當需要在AppDomain載入可執行程式時,可以使用ExecuteAssembly方法。
如,建一個控制台程式:
class Program { static void Main(string[] args) { Console.WriteLine("供應用程式定義域執行!"); Console.ReadKey(); } }
將上面程式產生的路徑儲存到:C:\Users\ChenZhuo\Desktop\ConsoleApplication1\ConsoleApplication1\bin\Debug\ConsoleApplication1.exe
下面我們建立一個應用程式定義域並執行上面那個程式集:
public class Program { static void Main(string[] args) { var domain = AppDomain.CreateDomain("MyAppDomain"); //執行指定的程式集 domain.ExecuteAssembly(@"C:\Users\ChenZhuo\Desktop\ConsoleApplication1\ConsoleApplication1\bin\Debug\ConsoleApplication1.exe"); Console.ReadKey(); } }
輸出結果如下:
需要注意的是如果需要卸載的話,只能把整個AppDomain卸載掉
然後我們就來到了網站應用程式程式的大門
也就是瀏覽器和ASP.NET的初次交涉,將請求封裝成HttpWorkRequest對象,並通過HttpRuntime.ProcessRequest()這個方法傳入封裝對象來處理請求
然後就得到了一個最最重要的對象HttpApplication 應用程式物件
為什麼說這個對象是最重要的呢?因為處理管道就在這個對象裡面,由於HTTP串連的特性----------->無狀態的短串連,所以我們的每一次請求都會建立一個HttpApplication
對象,為了節省記憶體的開銷,就有了一個HttpApplictionFactory的一個工廠對象來管理HttpApplication對象,同時還會產生一個混合對象HttpContext,
為什麼會有這個對象呢?就是為了方便我們進行管理,能用一個東西說明的就不用兩個東西來說明!!!!
然後呢,為了響應請求,ASP.NET需要很多很多的事情,於是就有了管道這個概念,
管道:
就是處理複雜問題的時候,將處理的過程分解為多個處理步驟,我們將這種經過多個步驟的處理方式稱為處理管道
自訂處理管道:
繼承自System.ComponentModel.Component
有一個Events集合管理
簡單的例子:
class Handler:Component { private static readonly object startEvent = new object(); private static readonly object stopEvent = new object(); public event EventHandler StartProcess { add { this.Events.AddHandler(startEvent, value); } remove { this.Events.RemoveHandler(startEvent, value); } } public event EventHandler StopProcess { add { this.Events.AddHandler(stopEvent, value); } remove { this.Events.RemoveHandler(stopEvent, value); } } protected void OnStartProcess(EventArgs e) { if (this.Events[startEvent]!=null) { ((EventHandler)this.Events[startEvent])(this, e); } } protected void OnStopProcess(EventArgs e) { if (this.Events[stopEvent] != null) { ((EventHandler)this.Events[stopEvent])(this, e); } } public void Process() { OnStartProcess(EventArgs.Empty); OnStopProcess(EventArgs.Empty); } }
static void Main(string[] args) { Handler h = new Handler(); h.StartProcess += h_StartProcess; h.StopProcess += h_StopProcess; h.Process(); Console.Read(); } static void h_StopProcess(object sender, EventArgs e) { Console.WriteLine("停止處理......"); } static void h_StartProcess(object sender, EventArgs e) { Console.WriteLine("開始處理....."); }
通過這個例子我們就可以看出來,管道可以通過事件暴露出來,也就是說我們可以自訂管道對應的處理方法,也就是過濾器,
在ASP.NET中為了拓展管道的事件分別引入了下面兩個類
1.IHttpModule
2.global.asax
但是在這兩個中來拓展的方法稍微有點不同,在IHttpModule
//先看定義 public interface IHttpModule { void Dispose(); void Init(HttpApplication context); }
所有所我們應該這樣來拓展
public void Init(HttpApplication context) { // 下面是如何處理 LogRequest 事件並為其 // 提供自訂日誌記錄實現的樣本 context.LogRequest += new EventHandler(OnLogRequest); context.BeginRequest += context_BeginRequest; }
並在Web.config中配置這個模組
<httpModules> <add name="模組名稱" type="命名空間.模組名稱,程式集名稱"/> </httpModules>
在 Global中就不是這樣配置了,需要滿足一定的要求
1.Application_HttpModule中的方法
2.滿足System.EventHandler
3.必須為public
然後我們就來到了處理管道,在這個管道中有19個處理事件,在這裡就不詳細的介紹了,我們只需要知道其中的幾個重要的方法就可以了
1.PostMapRequestHandler //找到對應的Handler
那是通過什麼樣的機制來找到對應的處理常式?比較一個網站不可能只有一個頁面,一個請求
我們可以通過設定檔來配置,格式如下:
在system.web配置元素的子項目httpHandlers來配置
add verb 通過一個逗號(,)分割的Http請求類型列表,例POST,GET,或者*代表全部 path 表示通過一個固定的URL路徑或者一個使用星號(*)的萬用字元來匹配請求的URL,例如*.xu 代表處理所有尾碼為xu的網頁 type 處理常式的類型,格式為("命名空間.類名","程式集名稱"); validate 如果設定為假,者在第一次匹配後,再不使用 removeclear
那麼為什麼我們的一般處理常式*.ashx沒有配置呢?是因為系統已經協助我們定義了
定義內容如下:
<add verb="*" path="*.ashx" type="System.web.UI.SimpleHandlerFactory" validate=true />
從上面這個配置節就可以看出來,拓展名為ashx的處理常式是被SimpleHandlerFactory進行管理的 SimpleHandlerFactory找到對應的ashx檔案 通過反射得到類的執行個體 通過GetHandler返回執行個體給HttpApplication
2.PostRequestHandlerExecute //執行Handler
3.EndRequest //結束請求
當然一般情況下我們請求的都是一個尾碼為*.aspx的不同頁面,它也是一個處理常式,定義如下
<add verb="*" path="*.aspx" type="System.web.UI.PageHandlerFactory" validate=true />
那麼頁面是怎麼產生的呢?我們知道一個HTML頁面除了字串還是字串,那是不是我們產生的頁面也都是字串?
那是當然了,這一切都是字串.為了方便使用ASP.NET把對應的標籤產生了一個一個對應的對象,這樣即方便管理又可以重複使用.
所有的控制項都繼承至Control包括Page
下面我們來看一下他們的繼承關係
>Control
>TemplateControl
>Page
>UserControl
>WebControl
>HtmlControl
>CompositeControl
>Panel
>Part
>WebPart
從這個關係中我們就可以看出來Page和UserControl是基於模板產生的,但是想想也不覺得奇怪,畢竟一個Page承擔了好多的東西
然後控制項又分為了伺服器控制項和Html控制項,這個其中Html控制項是靜態,服務端控制項是動態,當然在動態控制項中的內容也是Literal對象
既然有了模板,又有了控制項,我們基本上就可以做出一個簡單的網頁了,可是這樣並不能儲存狀態,於是為了儲存狀態,ASP.NET使用ViewState
來儲存對應對象的狀態,具體的做法就是將對象序列化為二進位對象,但是網頁不能有二進位對象,於是就把他轉換成了Base64格式的字串.
然後放在網頁中的隱藏欄位來進行儲存,這樣在我們回傳請求的時候就會順帶的把這個隱藏欄位中的內容發送到服務端.然後回複上一次的狀態.
具體的做法如下:
在頁面的事件處理管線InitComplete 和PreLoad 之間做狀態的恢複,然後再onLoad事件以後觸發對象引發的事件
然而載入和儲存需要實現一個介面---->IStateManager
public interface IStateManager { //表示控制項是否使用檢視狀態 bool IsTrackingViewState{get;} //管理檢視狀態的方法 void LoadViewState(Object state);//從檢視狀態取回資料 Object SaveViewState();//儲存檢視狀態 void TrackViewState();//開始使用檢視狀態 }
ASP.NET 學習的總結