細談asp.net如何處理應用程序-----c#菜鳥日記

   關於asp.net的不少,如:《asp.net典型模塊開發》,還有《asp.net項目與典型模塊開發》,《asp.net系統精髓》,這些書都是學習asp.net很好的書,作asp.net項目要用到,這些均可用c#編程語言開發asp.net項目。學會asp.net,PHP天然很容易。 程序員

   start, web

asp.net如何處理應用程序 編程

 

針對不一樣的請求,Asp.net要有不一樣的處理,在Asp.net中經過各類處理程序來分別進行處理。一般狀況下,根據請求的擴展名來肯定處理程序。其實在Asp.net中已經預約義了不少處理程序。 json

  first、處理程序與HttpApplication的關係 c#

  在Asp.net中,請求的真正處理是在處理程序這個環節。處理程序負責完成實際的請求處理工做,對於開發者來講,大多數的開發工做都是圍繞着處理程序展開的。實際上,接觸到HttpApplication事件處理的時候很少,HttpApplication除處理程序以外的做用,均可以理解爲是爲處理程序進行處理前的預處理和處理後的工做。 瀏覽器

  處理程序在不一樣的網站開發技術中,有着不一樣的名稱,在Asp.net中,稱爲HttpHandler。 緩存

  二、處理程序接口IHttpHandler和IHttpAsyncHandler 安全

  在Asp.net中,全部的處理程序類必須實現IHttpHandler接口或者實現IHttpAsyncHandler接口,一個同步,一個異步。 服務器

  IHttpHandler的定義以下: app

public interface IHttpHandler { bool IsReusable { get; } void ProcessRequest(HttpContext context); }

  通常處理程序裏實現的,就是這個東西。

  • ProcessRequest是IHttpHandler接口的主要方法,接收並經過一個HttpContext類型的請求上下文對象,處理程序能夠獲得關於處理請求所需的信息。經過  HttpContext的Response屬性能夠獲得響應的對象,用以向客戶端返回服務器處理的結果。
  • IsReusable屬性表示:「當這個處理程序對象在使用以後,是否還能夠被緩存起來,在之後的請求處理中再次使用」,這個屬性主要用來配合處理程序工廠使用。

  異步的處理程序派生自同步的處理程序接口,接口定義以下:

public interface IHttpAsyncHandler : IHttpHandler { IAsyncResult BeginProcessRequest(HttpContext context, AsyncCallback cb, object extraData); void EndProcessRequest(IAsyncResult result); }

  比IHttpHandler增長了兩個方法,BeginProcessRequest和EndProcessRequest方法。跟其餘異步方法使用同樣。

  三、在處理程序中使用會話

  處理程序是Asp.net網站中處理請求的基本單位。在默認狀況下,處理程序中甚至不能使用會話狀態,這樣能夠提升網站處理的速度。對於須要讀寫會話狀態的處理程序,必須實現一個特定的標記接口IRequireSessionState,這個接口定義在命名空間System.Web.SessionState中,其中沒有定義任何成員,因此,實現這個接口並不須要在類中增長任何成員。相似地,一樣定義在這個命名空間下的接口IReadOnlySessionState也沒有定義任何程序,用來標誌只須要讀取會話狀態的處理程序。

  這種沒有任何成員的接口,一般被稱爲標記接口,它的出現是因爲.Net早期沒有標籤(Attribute)而曇花一現,在Asp.net中,這是僅有的一例。

  HttpApplication的第9個事件AcquireRequestState事件和第13個事件ReleaseRequestState中,HttpApplication即經過判斷已經獲取得處理程序對象是否實現了這些接口來決定請求狀態的處理工做。

  四、處理程序工廠

  實現了處理程序接口的類就能夠被用來建立處理程序對象直接使用,若是再配合一個處理程序工廠,那麼就能夠實現處理程序對象的管理。

  好比,建立一個處理程序對象池,就能夠不用在每次使用處理程序的時候建立一個新的對象,而是能夠從池中取出一個現有的對象直接使用,以提升效率。

  在Asp.net中,做爲處理程序工廠的類必須實現接口IHttpHandlerFactory,這個接口在命名空間System.Web下,定義爲:

public interface IHttpHandlerFactory { IHttpHandler GetHandler(HttpContext context, string requestType, string url, string pathTranslated);    void ReleaseHandler(IHttpHandler handler); }

  其中GetHandler方法用來經過這個處理程序工廠獲取一個處理程序對象,ReleaseHandler方法用來釋放一個處理程序對象。

  關係圖以下:

  

  五、註冊處理程序

  每一種處理程序用來處理一類請求,不一樣的請求類別經過請求的擴展名來進行區分,處理程序與請求之間的匹配關係在網站的配置文件web.config中經過配置參數來進行設置。system.web配置元素的子元素httpHandlers用來配置網站所使用的處理程序。httpHandlers元素能夠包含三種子元素:add、remove和clear。

  add子元素有三個必選的屬性,做用以下:

  1. verb經過一個逗號(,)分割的HTTP請求類型列表來表示處理請求的類型,例如:GET,POST等;使用星號(*)表示處理全部類型的請求。
  2. path經過一個固定的URL路徑或者一個使用星號(*)的通配符來匹配請求的URL,例如,使用*.aspx表示這個處理請求將處理全部擴展名爲aspx的請求。
  3. type處理程序的類型名稱,或者是處理程序工廠的類型名稱,這個類型必須是類型的全名,包含命名空間、程序集(當類放在私有程序集時)。
  4. validate爲可選的屬性,若是設置爲false,那麼Asp.net在第一次匹配的請求調用以前,將不會試圖加載這個類。

  若是咱們定義了一個處理程序類,這個類定義在命名空間MyHandler下,名爲ValidateCodeHandler,這個類定義在私有程序集MyHandler.dll中,用來處理GET類型的請求,請求的擴展名爲vc,那麼配置參數以下:

複製代碼
<configuration>   <system.web>     <httpHandlers>       <add verb="GET" path="*.vc" type="MyHandler.ValidateCodeHandler,MyHandler.dll"/>     </httpHandlers>   </system.web> </configuration>
複製代碼

   在網站應用程序運行的時候,實際獲得的配置文件來自於系統的machine.config,系統的web.config和網站自身的web.config合併。在web.config中Asp.net已經預先配置了57中處理程序的映射,程序員還能夠經過處理程序接口擴展自定義的處理程序。

  六、使用處理程序生成驗證碼

  驗證碼是網站開發中常使用的安全技術,用於防止惡意的攻擊。

  咱們經過一個處理程序來生成發送到客戶端的驗證碼圖片,完成這個處理程序須要如下步驟:

  1. 建立一個類庫項目MyHandler,新的項目的默認命名空間也是MyHandler。
  2. 在類庫項目MyHandler中添加一個新的類ValidateCodeHandler,實現IHttpHandler接口。爲了在處理程序中使用Session狀態管理,同時實現IRequiresSessionState接口。
  3. 在ProcessRequest方法中完成驗證碼生成的操做。
  4. 在網站項目中引用這個類庫項目。
  5. 在網站項目的配置文件web.config中註冊這個處理程序。
  6. 在須要驗證碼的頁面上使用處理程序生成的驗證碼。

  新建一個Asp.net Web程序:

複製代碼
public class ValidateCodeHandler : IHttpHandler,IRequiresSessionState { private static Random random = new Random(); public void ProcessRequest(HttpContext context) { context.Response.ContentType = "image/jpeg"; Image image = new Bitmap(60, 30); //生成隨機數 int code = random.Next(1000, 10000); string codeString = code.ToString(); //使用會話狀態 context.Session["Code"] = codeString; using (Graphics g = Graphics.FromImage(image)) { g.Clear(Color.WhiteSmoke); StringFormat sf = new StringFormat(); sf.Alignment = StringAlignment.Center; sf.LineAlignment = StringAlignment.Center; g.DrawString(codeString, new Font("Arial", 14), Brushes.Blue, new RectangleF(0, 0, image.Width, image.Height), sf); } context.Response.ContentType = "image/jpeg"; image.Save(context.Response.OutputStream, ImageFormat.Jpeg); } public bool IsReusable { get { return false; } }
複製代碼

  而後在web.config裏面增長以下配置:

<httpHandlers> <add verb="GET" path="*.vc" type="WebApplication1.ValidateCodeHandler"/> </httpHandlers>

  而後啓動項目,隨便打開一個本系統下.vc後綴的路徑:

  

  從項目中咱們能夠看到,全部.vc後綴的路徑,Asp.net都會映射到這個類中處理。

2、通常處理程序

  雖然經過標準的方式能夠建立處理程序,可是實現的步驟比較複雜,爲了方便網站開發中對於處理程序的應用,從Asp.net 2.0開始,Asp.net提供了稱爲通常處理程序的處理程序,容許咱們私用比較簡單的方式定義擴展名爲ashx的專用處理程序。

  經過Visual Studio 2010建立的通常處理程序將會生成兩個文件Handler1.ashx和Handler1.ashx.cs。其中Handler1.ashx文件中的內容以下所示:

<%@ WebHandler Language="C#" Class="Handler" %>

  對應的代碼文件Handler1.ashx.cs中的內容如如下代碼所示。能夠很是清楚地看到,這就是一個實現IHttpHandler接口的類,以下:

複製代碼
public class Handler1 : IHttpHandler { public void ProcessRequest(HttpContext context) { context.Response.ContentType = "text/plain"; context.Response.Write("Hello World"); } public bool IsReusable { get { return false; } } }
複製代碼

  通常處理程序實際上就是一個處理程序類,這個處理程序被Asp.net直接在系統的配置文件中映射到了ashx擴展名的請求上。這樣,咱們就不須要在配置文件中進行配置了。

  一、通常處理程序工廠

  對於通常處理程序來講,擴展名請求的程序並不須要程序員在web.config中進行配置,這是由於這個處理程序已經定義在系統配置文件的web.config。因此瀏覽器能夠直接請求擴展名爲ashx的地址:

<add path="*.ashx" verb="*" type="System.Web.UI.SimpleHandlerFactory" validate="True" />

  經過配置文件,咱們能夠看到,對於擴展名爲ashx的請求是經過定義在命名空間System.Web.UI下的SimpleHandlerFactory處理程序工廠來完成的。

  當請求一個ashx擴展名的服務器上的資源的時候,SimpleHandlerFactory將找到對應的ashx文件,經過這個文件找到對應的處理程序,最後,SimpleHandlerFactory經過反射建立一個此類型的處理程序對象實例,並經過GetHandler方法返回給HttpApplication,完成最終的請求處理過程。

  二、使用通常處理程序的場合

  對於Asp.net網站來講,最多見的處理結果就是HTML網頁,生成網頁的工做一般使用擴展名爲aspx的Web窗體來完成,對於處理結果不是HTML的請求,均可以經過通常處理程序來完成。例如生成RSS Fed,XML,圖片等。

  通常處理程序是Asp.net網站中最爲簡單、高效的處理程序,在處理返回類型不是HTML的請求中有着重要的做用。

  三、使用通常處理程序生成驗證碼圖片

  例如,在前面實現的驗證碼處理程序用通常處理程序可以更快地完成,直接在ProcessRequest方法中實現功能就能夠了,原來的第一、二、四、5步均可以省略。

複製代碼
public class Handler1 : IHttpHandler, IRequiresSessionState { private static Random random = new Random(); public void ProcessRequest(HttpContext context) { context.Response.ContentType = "image/jpeg"; Image image = new Bitmap(60, 30); //生成隨機數 int code = random.Next(1000, 10000); string codeString = code.ToString(); //使用會話狀態 context.Session["Code"] = codeString; using (Graphics g = Graphics.FromImage(image)) { g.Clear(Color.WhiteSmoke); StringFormat sf = new StringFormat(); sf.Alignment = StringAlignment.Center; sf.LineAlignment = StringAlignment.Center; g.DrawString(codeString, new Font("Arial", 14), Brushes.Blue, new RectangleF(0, 0, image.Width, image.Height), sf); } context.Response.ContentType = "image/jpeg"; image.Save(context.Response.OutputStream, ImageFormat.Jpeg); } public bool IsReusable { get { return false; } } }
複製代碼

  通常處理程序要使用Session也是要實現接口IRequiresSessionState的。

  四、使用通常處理程序生成JSON

   代碼示例:

複製代碼
public class UploadPercentHandler : IHttpHandler { public void ProcessRequest(HttpContext context) { Person p = new Person(); p.Id = 1; p.Name = "撼地神牛"; JavaScriptSerializer jss = new JavaScriptSerializer(); string json = jss.Serialize(p); context.Response.ContentType = "application/json"; context.Response.Write(json); } public bool IsReusable { get { return false; } } } public class Person { public int Id { get; set; } public string Name { get; set; } }
複製代碼

  輸出:

  

3、頁面處理程序

  Asp.net使用模板的方式來生成一個處理程序。模板的擴展名爲aspx,經過一個內置的處理程序工廠PageHandlerFactory將aspx形式的模板編譯生成處理程序代碼,而後,將這個處理程序返回給HttpApplication完成請求的處理。aspx形式的模板文件能夠直接經過文本編輯器進行編輯。

  一、頁面處理工廠

  在Asp.net的系統配置文件中,已經進行了以下的配置,能夠看到,對於擴展名爲aspx的請求,將由PageHandlerFactory這個處理程序工廠進行處理。

  配置以下:

<add path="*.aspx" verb="*" type="System.Web.UI.PageHandlerFactory" validate="True" />

  這個類定義在命名空間System.Web.UI下,具體的定義以下:

public class PageHandlerFactory : IHttpHandlerFactory

  這是一個典型的處理程序工廠,用來返回一個實現IHttpHandler接口的處理程序對象實例。PageHandlerFactory將尋找匹配請求名稱的aspx文件,而後將這個模板文件進行解析,經過代碼生成機制生成相應的頁面類。這個頁面類派生自Page類,Page類定義在命名空間System.Web.UI下,類的定義爲:

public class Page : TemplateControl,IHttpHandler

  aspx模板文件與Page類和生成類之間的關係是:

  PageHandlerFactory讀取aspx文件,將aspx文件解析生成一個派生自Page的類;

  aspx模板的解析和代碼生成僅僅出如今第一次處理的時候,之後的請求將直接使用已經編譯生成的程序集,因此,這個處理過程並不會下降網站的處理速度。

  二、建立頁面處理程序

  在PageHandlerFactory的內部,經過PageParser這個類解析指定的aspx文件生成Page類的派生類,這個派生類用來建立頁面處理程序的對象實例。這個類定義在命名空間System.Web.UI中,完整的定義以下:

public sealed class PageParser

  PageParser有一個靜態方法

GetCompiledPageInstance(string virtualPath,string inputFile,HttpContext context)

  GetCompiledPageInstance方法內部又使用了BuildManager類來建立頁面對象實例,這個類定義在命名空間System.Web.Compilation下,完整的類定義以下:

public sealed class BuildManager

  BuildManager的CreateInstanceFromVirtualPath方法經過頁面的虛擬路徑經過代碼生成獲得派生的頁面類,而後經過反射建立這個頁面對象,代碼以下:

public static Object CreateInstanceFromVirtualPath(string virtualPath,Type requiredBaseType)

  三、生成的代碼

  對於一個aspx模板文件來講,通常狀況下將對應存在一個同名的cs後臺代碼文件,其中定義了一個與頁面同名的類,經過代碼文件能夠看到這個類派生自Page的類。
  PageHandlerFactory經過aspx文件將生成兩個類,一個爲與後臺代碼中定義的類同名的部分類,這個部分類將與後臺代碼中定義的類在編譯的時候合併爲一個派生自Page的頁面派生類。可是,在Asp.net中,建立實際頁面對象的類並非這個類,而是生成的第二個類,通常狀況下,這個類的名字爲頁面的名字後面加上下劃線和aspx。這纔是實際建立頁面對象的頁面類。

  假設有一個Person.aspx,那麼應該存在一個對應的後臺代碼文件Person.aspx.cs,其中定義了Person這個Page的派生類。

  經過PageHandlerFactory,Person.aspx將生成兩個類,部分類Person和Person_aspx。其中,後臺代碼文件中的Person將和生成的部分類Person在編譯的時候合併爲一個完整的Person類定義,而Person_aspx則是從Person派生的一個頁面類,用來建立實際的頁面對象實例。

  四、使用頁面處理程序

  因爲頁面處理程序是經過模板生成的,因此,大多數狀況下,咱們只要建立好這個aspx的模板就能夠了,HttpApplication會經過PageHandlerFactory建立這個生成的處理程序,而後使用這個處理程序完成服務器的處理任務。如今,若是咱們須要經過處理程序生成一個網頁的話,只須要設計一個aspx頁面便可。

  在一些特殊的狀況下,咱們須要建立一些生成HTML輸出的程序。可是這些程序並不但願可以被客戶端直接請求,那麼,能夠藉助PageParser或者BuildManager經過aspx格式的模板來建立一個自定義的處理程序完成處理任務。

OK。

相關文章
相關標籤/搜索