SharePoint基礎之六- SharePoint基礎架構中涉及的ASP.NET架構

來源:互聯網
上載者:User

ASP.NET架構代表著在IIS和ISAPI編程模型之上的一個重要的生產力層. 如果你熟悉ASP.NET開發的話, 你就會知道它為你的應用程式邏輯編寫Managed 程式碼提供了便利, 比如說C#, VB.NET, 並且允許你在由Microsoft Visual Studio提供的面向生產力的可視化編輯器中工作. ASP.NET架構還提供了許多其他有價值的抽象, 來協助開發人員進行狀態管理, 資料繫結, 導航 以及資料緩衝.

 

ASP.NET架構是由一個叫做aspnet_isapi.dll的ISAPI extension實現的. ASP.NET的基礎配置涉及: 在IIS網站或虛擬目錄的層次, 為ASP.NET的檔案尾碼註冊映射的應用程式, ASP.NET的檔案尾碼包括.aspx, .ascx, 和.asmx. 當IIS看到一個指向這些檔案類型的請求的時候, 他會把這個請求送給aspnet_isapi.dll, 讓它來處理, 這個dll會高效地將控制轉移給ASP.NET架構. 所以說, ASP.NET架構處理一個請求的方式很大程度上取決於目標檔案的檔案類型(副檔名).

 

ASP.NET架構像一個獨立的ASP.NET應用程式一樣地執行指向IIS網站和虛擬目錄的請求. 在每一個ASP.NET應用程式的身後, 都有一個包括一堆檔案的根目錄. 這種架構保證了ASP.NET應用程式的部署是一種非常簡單的x-copy風格. 你可以簡單地在Web伺服器上建立一個新的虛擬目錄, 然後拷貝你的ASP.NET應用程式的檔案到根目錄下. 當然, 有一點小麻煩的是在Web場環境中建立虛擬目錄, 然後將同樣的檔案部署到場中的所有前端伺服器上.

 

每個ASP.NET應用程式都可以在它的根目錄下被獨立地配置web.config檔案. web.config檔案是一個基於xml的檔案, 包含許多元素, 用於控制ASP.NET架構中的各種各樣的feature的行為, 比如說編譯啦, 頁面渲染啦, 狀態控制了什麼的. 一個簡單的web.config檔案看起來像下面這樣:

<?xml version="1.0" encoding="utf-8" ?><configuration>  <system.web>    <customErrors mode="On" />    <httpRuntime maxRequestLength="51200" />    <authentication mode="Windows" />    <identity impersonate="true" />    <authorization>      <allow users="*" />    </authorization>  </system.web></configuration>

注意到ASP.NET架構在運行每一個ASP.NET應用程式的時候, 都有一定程度的隔離性. 即使是在你已經配置了多個ASP.NET應用程式運行在同一個IIS Application Pool中的時候, 也有隔離性. ASP.NET架構提供了運行在同一個IIS工作者進程中的對多個ASP.NET應用程式之間的隔離, 隔離方式是把它們分別載入到分開的.NET Framework AppDomain中.[學友注: 關於AppDomain, 可以參考文章走近.NET AppDomain]

 

ASP.NET頁面

===========

頁面(page)是ASP.NET架構中最有價值的抽象之一. 開發人員構建ASP.NET應用程式, 最典型的方式是在Visual Studio的可視化設計介面上拖拽伺服器控制項, 和通過標準的屬性單來修改頁面和控制項的屬性. ASP.NET架構和Visual Studio還使得向頁面中添加處理邏輯相對更加簡單了, 達到這個目的的方式是在頁面級上的響應事件中和在控制項級的事件中通過編寫Managed 程式碼.

 

在物理層面, ASP.NET應用程式中的一個頁面是一個以.aspx尾碼結尾的, 儲存在Web伺服器上的檔案, 在它被用戶端請求時, 它會被編譯為一個dll檔案. 考慮下面的aspx頁面定義, 它包含一個伺服器端控制項和一個簡單的事件處理常式.

<%@ Page Language="C#" %><script runat="server">  protected override void OnLoad(EventArgs e) {    lblDisplay.Text = "Hello, ASP.NET";  }</script><html><body>  <form id="frmMain" runat="server">    <asp:Label runat="server" ID="lblDisplay" />  </form></body>

在後台, ASP.NET架構做了不少工作來把.aspx檔案編譯成為一個dll檔案. 首先, 它必須先將aspx檔案解析並產生一個C#(或VB.NET)的源檔案, 源檔案中包含一個繼承自Page類的公有類, Page類是定義在System.Web.UI命名空間下的, 存在於system.web.dll這個程式集中. 當ASP.NET頁面解析器產生這個繼承自Page的類時, 它建立一個控制項的樹形結構, 包括頁面中定義的所有的伺服器端控制項. 頁面解析器同時添加需要的代碼來勾住頁面中定義的任何的事件處理常式.

 

一旦ASP.NET頁面解析器建造好了.aspx的源檔案, 它就開始編譯這個源檔案成為一個DLL. 這個編譯自動發生在這個.aspx頁面第一次被請求的時候. 一旦ASP.NET運行時編譯好了aspx檔案的DLL, DLL的一份拷貝會被用來為所有後來的指向同樣aspx檔案的請求服務. 然而, ASP.NET運行時會監視DLL的時間戳記, 如果它發現與DLL相關聯的aspx檔案被更新了, 它就會重新編譯來重建那個DLL.

 

ASP.NET架構如此流行的原因之一, 就是因為它方便的伺服器端控制項. 使用與ASP.NET架構一同release的開箱即用(out-of-box)的控制項建立頁面非常容易.控制項有很多, 比如validation控制項, calendar控制項, 還有支援資料繫結的控制項, 比如GridView控制項還有Repeater控制項. 還有呢, 開發人員創作自訂的控制項並把它用在頁面裡也是相對容易的.

 

主版頁面

================

ASP.NET 2.0引入了主版頁面(master page), 它提供了一種非常高效的建立頁模板的方式. 特別地, 一個主版頁面定義了可以在許多不同頁面間使用的通用元素(比如說頂部橫幅top banner), 還有網站導覽控制項. 在主版頁面中定義的布局可以被很多跟這個主版頁面連結到一起的頁面使用. 在ASP.NET技術中, 與一個主版頁面連結到一起的頁面叫做content page(內容頁). 主版頁面與內容頁的基本關係在下面可以看到圖示:

舉例, 假設你希望建立一個主版頁面, 用來定義一個HTML布局, 這個布局包括一個橫幅在頁的頂部. 你應該建立一個尾碼名為.master的檔案作為開始, 就叫default.master吧. 下一步你應該在頁面的頂部添加一個@Master指令. 然後, 在下面你定義頁面的HTML布局, 添加並命名placeholders, 就如下面的例子一樣:

<%@ Master %><html><body>  <form id="frmMain" runat="server">    <table width="100%">      <tr>        <td> <!-- Display Litware Banner -->          <h1>Litware Inc.</h1><hr />        </td>      </tr>      <tr>        <td> <!-- Display Main Body of Page -->          <asp:contentplaceholder id="PlaceHolderMain" runat="server" />        </td>      </tr>    </table>  </form></body></html>

 

當你想建立一個內容頁時, 你應該建立一個.aspx檔案, 然後添加一個@Page指令, 其中包括MasterPageFile屬性. 一旦你決定你想要取代主版頁面中的哪一個命名的placeholder, 你就為這個取代操作定義一個Content元素. 接下來是一個簡單的內容頁連結起一個主版頁面的例子, 代碼中取代了主版頁面中的名為PlaceHolderMain的placeholder.

<%@ Page Language="C#" MasterPageFile="~/default.master" %><script runat="server">  protected override void OnLoad(EventArgs e)   {    lblDisplay.Text = "Hello World";  }</script><asp:Content ID="main" Runat="Server" ContentPlaceHolderID="PlaceHolderMain" >  <asp:Label ID="lblDisplay" runat="server" /></asp:Content>

注意當你建立了一個內容頁並指向了一個主版頁面了的時候, 所有你想添加的的HTML必須寫在指向某個名字的placeholder的Content元素中. 如果你在Content元素之外寫了HTML代碼或者是伺服器端控制項, 那麼這個頁面就不會被編譯. 但是, 如同你在之前的例子中看到的, 你可以在Content元素之外添加一個指令碼塊, 並在指令碼塊中添加任何你想添加的代碼.

 

當一個主版頁面定義了一個命名了的placeholder, 你並不需要一定總是在你的內容頁中取代它. 因為, 主版頁面建立帶有的預設內容的placeholder.  任何指向那個主版頁面的內容頁, 只要不包括那個命名了的placeholder, 就會得到主版頁面中定義的預設內容.  另一個串連到同樣主版頁面的內容頁, 並且其中包含了那個命名的placeholder, 會用自己的自訂內容取代預設內容.

最後, 注意不管是誰, 只要他建立了主版頁面, 那他就得決定placeholder的名字, 還要決定哪個包含什麼樣的預設內容. 這對於設計WSS網站的頁面時很重要, 因為你建立的內容頁將會指向由WSS團隊建立的主版頁面. 在這種情況下, 你必須學會WSS團隊定義了什麼placeholder, 還有哪些種類的內容是可以取代的.

 

HTTP請求的pipeline

================

在面向高產的頁面和伺服器端控制項架構之下, ASP.NET架構為想要在更深一個層次的開發人員暴露了HTTP請求Pipeline. 他給開發人員提供了可以跟ISAPI編程模型在某種程度相比的控制. 然而, 當你為HTTP請求pipeline建立組件的時候, 你卻可以使用如C#或VB.NET一樣的Managed 程式碼. 你還可以使用由ASP.NET提供的API, 這可比直接使用ISAPI編程模型容易多了.

 

展現了HTTP request pipeline和它的三個可以替代的組件類型: HttpHandler, HttpApplication, 和HttpModule. 當請求進來的時候, 他們被排入隊列, 並被賦給一個工作者線程, 然後通過與這三個組件類型的互動來處理這個請求.

 

 

任何請求的最後的終點, 你可以在圖中看到, 是HttpHandler類, 它繼承了IHttpHandler介面. 作為一個開發人員, 你可以建立一個自訂的HttpHandler組件, 然後通過在web.config中添加設定元素來把你的HttpHandler插入到HTTP request pipeline中.

 

Http Request Pipeline在HttpHandler之前放置了一個HttpApplication組件. 在一個應用程式範圍的基礎上, 進來的請求在到達HttpHandler之前, 總是通過HttpApplication來路由的. 因此, 給了HttpApplication一個不管最後被路由到哪個HttpHandler, 它總能預先處理任何請求的能力. 這個預先處理階段是通過一系列的在HttpApplication中定義的事件來控制的, 比如說BeginRequest, AuthenticateRequest, 和AuthorizeRequest.

 

在你不想使用自訂的HttpApplication組件的情形下, ASP.NET使用一個標準的HttpApplication對象來初始化Http Request Pipeline. 然而, 你可以通過建立一個叫做global.asax的檔案, 把它放到ASP.NET應用程式的根目錄下來取代這個標準的HttpApplication組件. 舉個例子, 你可以建立一個看起來像下這樣的global.asax:

<%@ Application Language="C#" %><script runat="server">  protected void Application_AuthenticateRequest(object sender, EventArgs e) {    // your code goes here for request authentication  }  protected void Application_AuthorizeRequest(object sender, EventArgs e) {    // your code goes here for request authorization  }</script>

 

HTTP Request Pipeline中可以替換的第三個組件類型是HttpModule. HttpModule跟HttpApplication組件相似, 它被設計用來處理HttpApplication類定義的事件, 並且這些事件的處理髮生在請求被傳送給任何一個HttpHandler類型之前. 比方說, 你可以建立一個自訂的HttpModule組件來處理請求層次的時間, 比如說BeginRequest, AuthenticateRequest, 和AuthorizeRequest. 跟HttpHandler一樣, HttpModule類是通過一個介面來定義的. 你可以建立一個實現IHttpModule介面的類, 然後通過在web.config檔案中添加配置元素來把你的HttpModule插入到Http Request Pipeline中.

 

鑒於HttpApplication組件可以被定義為像帶著.asax尾碼的文字檔一樣的簡單, 自訂的HttpModule組件總是會被程式集DLL中的類一樣被編譯. 要添加一個自訂的HttpModule組件到Http Request Pipeline中, 你就得在web.config檔案中添加入口.

 

儘管HttpApplication和HttpModule組件在所做的事情上非常相似, HttpModule包含一些值得注意的不同. 首先, 不像HttpApplication組件那樣必須在一個應用程式中只添加一個HttpApplication組件, 對於HttpModule組件, 你的添加沒有數量上的限制. ASP.NET的web.config檔案可以添加多個不同的HttpModule組件. 第二, HttpModule組件可以被設定在機器的水平上. 事實上ASP.NET架構附帶了好幾個不同的HttpModule組件, 他們被自動的配置在機器機上運作, 來為ASP.NET提供諸如Windows authentication, Forms Authentication和輸出緩衝等功能.

 

對於HTTP Request Pipeline 我們要討論的最後一個組件是HttpContext. 隨著ASP.NEt初始化一個請求並發送給HTTP Request Pipeline, 它還用HttpContext類建立一個對象, 並使用重要的上下文相關的資訊來初始化這個對象.

 

從時間的角度來說, 在ASP.NET在HTTP Request Pipeline中的任何自訂的代碼有機會執行之前, HttpContext對象就已經被建立出來了, 認識到這一點很重要. 這意味著你永遠可以使用HttpContext對象和它的子物件進行編程, 比如說Request, User, 和Response. 無論何時你開發一個用來在Http Request Pipeline中啟動並執行組件, 你都可以寫像下面這樣的代碼:

HttpContext currentContext = HttpContext.Current;string incomingUrl = currentContext.Request.Url;string currentUser = currentContext.User.Identity.Name;currentContext.Response.Write("Hello world");

 

<Inside Microsoft Windows SharePoint Services 3.0>

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.