ASP.NET

ASP.NET的事件模型

ASP.NET 的原始設計構想，就是要讓開發人員能夠像 VB 開發工具那樣，可以使用事件驅動式程式開發模式 (Event-Driven Programming Model) 的方法來開發網頁與應用程式，若要以ASP技術來做到這件事的話，就必須要使用大量的輔助資訊，像是查詢字串或是表單欄位資料來識別與判斷物件的來源、事件流向以及呼叫的函式等等，需要撰寫的程式碼量相當的多，但 ASP.NET 很巧妙利用表單欄位和JavaScript指令碼把事件的傳遞模型隱藏起來了。
ASP.NET 的事件模型是由 <form runat="server"></form> 以及數個 Hidden Field 組合而成，基於 HTTP 模型的限制，所有的網頁程式在執行結果輸出到用戶端後，程式就會結束執行，為了維護在 ASP.NET 網頁與控制項的狀態資料，因此在輸出 ASP.NET 控制項時，ASP.NET 會將部份狀態資料儲存到網頁的 Hidden Field 中，這類型的狀態資料稱為 ViewState（ID 為 __VIEWSTATE），在伺服器端即會被解譯出狀態與事件資料。在大多數的內建 Web 控制項中都有使用到這個機制，因此在使用大量 ASP.NET Web 控制項的網頁中，會有許多的 ViewState 會存放在網頁中並隨著 HTTP 資料流輸出到用戶端，ViewState 在輸出時，會被加密為一組亂碼字串，其金鑰值定義在電腦中，並且每一個物件都會被序列化 (serialize) 成字串（因此若是自訂物件要放到 ViewState 時，則應要讓它支援序列化），再輸出到 __VIEWSTATE 欄位中，在每次的網頁來回時都會被傳輸，較大的 ViewState 會讓網頁大小膨脹，不利於快速的網路傳輸，不過 ASP.NET 本身有提供將 ViewState 關閉的功能，因此如果控制項不需要狀態儲存時，可將它關閉以減少輸出的大小。
為確保控制項的事件能夠確實被引發，讓事件驅動能夠被執行，因此控制項事件引發命令時需要的參數，是交由 JavaScript 指令碼在用戶端引發時，填入另一個 Hidden Field（ID 為 __EVENTTARGET 以及 __EVENTARGUMENT），並且引發表單的送出指示 (submit)，傳送到伺服端後，伺服端的 HttpApplication 中的工具函式會解析 __EVENTTARGET 和 __EVENTARGUMENT 欄位中的資訊，並且交由控制項所實作的 RaisePostBackEvent() 來引發事件，並由 .NET Framework 內部的事件處理機制接手處理（呼叫控制項設定的事件處理常式）。

繪製技術

熟悉 ASP 技術的人都知道，程式碼都是混在 HTML 標籤之間，以輸出預期需要的 HTML 指令，這個技術在 ASP.NET 中，由各控制項的繪製 (Render) 機制包裝起來了，繪製機制裝載了 HtmlTextWriter 物件，由它來產生 HTML 指令，它會輸出至 HttpContext 的 Response 輸出資料流中（即 ASP 技術的 Response.Write()），下列程式碼為繪製技術的範例：
[System.Security.Permissions.PermissionSet(System.Security.Permissions.SecurityAction.Demand, Name="FullTrust")] 
protected override void Render(HtmlTextWriter output) 
{
    if ( (HasControls()) && (Controls[0] is LiteralControl) ) 
    {
        output.Write("<H2>Your Message: " + ((LiteralControl) Controls[0]).Text + "</H2>");
    }}
為了讓控制項的輸出有階層性，ASP.NET 開發了一個可以階層化輸出控制項 HTML 指令的方式，稱為控制項樹 (Control Tree)，藉由控制項樹，可以讓各個控制項的輸出可以階層化，不論是否是收納型控制項，還是一般型的控制項，都可以按照控制項的順序來輸出。

應用程式層級物件

Application 物件會在應用程式的 Application_OnStart 事件中初始化，並使用名稱來識別資料（它是一個 NameObjectCollectionBase 集合的實作品），它會儲存在應用程式的範圍內，所有的連線（使用者）都可以使用，屬於共用型的儲存體，適合儲存所有使用者都可使用的資料，在多人使用的情況下，可以適當的使用 Lock/Unlock 的機制來確保應用程式狀態的更新。
Application.Lock();Application["PageRequestCount"] = 
    ((int)Application["PageRequestCount"])+1;Application.UnLock();

連線層級物件

連線層級的物件是 Session，以瀏覽器的執行個體為識別單位，資料依瀏覽器的執行個體來儲存，在瀏覽器的執行個體第一次連到應用程式時，ASP.NET會設定一個Session ID，並且使用它來識別 Session，每一個 Session 都是 ICollection 與 IEnumerate 的實作，用 key 來識別資料值，並且具有時間的限制 (timeout)，若超出時限時伺服器會自動清理掉，預設的 Session 時限為 20 分鐘。Session ID 的演算法是由 RNGCryptoServiceProvider（密碼編譯亂數產生器提供者）產生，並編碼成一個 Session ID 字串（例如 anf4vuup3xiq0arjlqla2l55 這樣的字串）儲存在伺服器中，用以識別不同的 Session 個體。
為因應不同的用戶端，ASP.NET 設計了不同的 Session ID 存放機制，像是舊式的瀏覽器或是行動用戶端這種不支援本機儲存cookie的裝置時，ASP.NET 可以直接在 URL 中加上 Session ID 的識別，像是 http://www.example.org/(anf4vuup3xiq0arjlqla2l55)/profile.aspx 這樣的 URL，可以由開發人員自行設定，或是使用 AutoDetect 設定來讓 ASP.NET 自行判斷要使用的 Session ID 存放方式。
Session ID 的產生方法可以由程式開發人員自訂，藉由覆寫 SessionIDManager 的 CreateSessionID() 方法來自訂。
using System;using System.Configuration;using System.Web.Configuration;using System.Web;using System.Web.SessionState;namespace Samples.AspNet.Session{

  public class GuidSessionIDManager : SessionIDManager
  {

    public override string CreateSessionID(HttpContext context)
    {
      return Guid.NewGuid().ToString();
    }


    public override bool Validate(string id)
    {
      try
      {
        Guid testGuid = new Guid(id);

        if (id == testGuid.ToString())
          return true;
      }
      catch
      {
      }

      return false;
    }
  }}

部件

ASP.NET 是開發 Web 應用程式的基礎架構 (framework)，除了它內部的運作方法外，對外也顯露了許多的開發支援，讓開發人員可以利用它來發展出許多強大的 Web 應用程式解決方案。

網頁

ASP.NET 最基礎的底層為網頁 (Page)，網頁由 System.Web.UI.Page 類別來提供基礎支援，包含了頁面的事件以及物件繪製的引發點（Page 類別本身是一個 HTTP Handler 的實作品）。ASP.NET 網頁在微軟的官方名稱中，稱為 Web Form，除了是要和Windows Forms作分別以外，同時也明白的刻劃出了它的主要功能：「讓開發人員能夠像開發 Windows Forms 一樣的方法來發展 Web 網頁」。因此 ASP.NET Page 所要提供的功能就需要類似 Windows Forms 的表單，每個 Web Form 都要有一個 <form runat="server"></form> 區段，所有的 ASP.NET 伺服器控制項都要放在這個區域中，這樣才可以讓 ViewState 等伺服器控制能夠順暢的運作。
在網頁中也可以使用程式碼，以類似於ASP時代的撰寫方式來開發，此種開發方式稱為 inline code，在 ASP.NET 的程式開發模式中，inline code ，要放在 <script runat="server"></script> 區域中，如下列的範例程式：
<%@ Page Language="C#" %>
 
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN""http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
 
<script runat="server">
 
    protected void Page_Load(object sender, EventArgs e)
    {
        Label1.Text = DateTime.Now.ToLongDateString();
    }
 
</script>
 
<html xmlns="http://www.w3.org/1999/xhtml"><head runat="server">
    <title>Sample page</title></head><body>
    <form id="form1" runat="server">
    <div>
        The current time is: <asp:Label runat="server" id="Label1" />
    </div>
    </form>
 
</body></html>
另一種模式則是將程式碼和網頁分離，這種模式稱為程式碼後置 (Code-Behind)，這個方法可以將程式碼獨立到一個檔案中，網頁可以保持較乾淨的狀態，讓維護網頁程式的複雜度降低很多，在網頁的提示指令 (directive) 中，可以設定程式碼後置的參數，像是 Inherit、CodeFile、Class 等參數。
<%@ Page Language="C#" CodeFile="SampleCodeBehind.aspx.cs" Inherits="Website.SampleCodeBehind" 
AutoEventWireup="true" %>
而一個典型的程式碼後置例子為：
using System;
 
namespace Website{
public partial class SampleCodeBehind : System.Web.UI.Page
{
protected override void Page_Load(EventArgs e)
{
base.OnLoad(e);
}
}}
使用程式碼後置模式的設定時，可以讓 ASP.NET 執行引擎在載入網頁時，由程式碼後置參數取得對應的類別資訊，藉以使用 Reflection 的方式來執行後置的程式碼。
ASP.NET 可以支援HTML和XHTML兩種網頁內容，但在Visual Studio.NET中，預設是使用 HTML，但在Visual Studio 2005以後的版本，則一律都改用XHTML格式。

應用程式服務

應用程式服務 (application services) 是在 ASP.NET 2.0 中才開始提供，它以 Provider-based Pattern 為主，實作出數個網站的常用服務，包含會員服務 (Membership Service)、角色服務 (role service)與設定檔服務 (profile service) 等。
會員服務由 Membership 以及其資料提供者 MembershipProvider 構成，應用程式使用 Membership 所顯露的方法來操作，它會將要求轉送給指定的 MembershipProvider 實作來處理，ASP.NET 目前支援來自於資料庫的 SqlMembershipProvider（支援 SQL Server）以及來自於Active Directory的 ActiveDirectoryMembershipProvider，開發人員也可以自行由 MembershipProvider 繼承來實作自訂的會員服務資料提供者。
角色服務與會員服務類似，由 Role 以及其資料提供者 RoleProvider 構成，應用程式使用 Role 所顯露的方法操作，由 RoleProvider 實作提供資料服務，目前內建的 RoleProvider 有來自 Active Directory 或 XML 檔案的 AuthorizationStoreRoleProvider，由 SQL Server 供應資料的 SqlRoleProvider，以及支援 Windows 角色的 WindowsTokenRoleProvider 三種，開發人員可自行實作 RoleProvider 的方法以發展出自訂的角色服務提供者。
設定檔服務是一個特殊的服務，它結合了 .NET Framework 的 CodeDOM 開發模式，以及 System.Web.Profile 命名空間的 ProfileBase、ProfileInfo 與 ProfileManager 等類別，組合出完整的設定檔支援，其資料來源也是以 Provider-based Pattern 為主，由 ProfileProvider 提供，ASP.NET 內建由 SQL Server 資料庫建立的 SqlProfileProvider，其欄位係由開發人員在 ASP.NET 組態檔中自行定義，再由 ASP.NET 動態產生強型別的欄位屬性。
設定檔服務也是作為 ASP.NET 2.0 的網頁組件 (Web Part Framework) 所需要的設定檔儲存支援，Web Part Framework 可以讓開發人員可以開發出具備個人化能力 (Personalization) 的網頁組態方案，讓使用者可以用自行新增與拖放的方式來設計自己的網頁布置，所需要的設定儲存即由設定檔服務處理。
另一個需要和應用程式服務配合使用的功能為 Web 事件架構 (Web Event Framework)，它需要由應用程式服務提供資料結構，它也有 Provider-based Pattern，並可以支援數種的事件資料提供者。

延展性支援

除了 ASP.NET 網頁以外，.NET Framework 還提供了兩種可以由開發人員自行發展處理模型的模組，一種是HTTP Handler，另一種則是HTTP Module。
HTTP Handler（副檔名為 .ashx）由 System.Web.IHttpHandler 介面定義了必要的方法（可支援非同步的 HTTP Handler 稱為 HTTP Async Handler，由 System.Web.IHttpAsyncHandler 介面定義），其中最重要的方法是 ProcessRequest() 方法，開發人員必須要實作這個方法，才能夠讓 HTTP Handler 有作用，它也可以透過 ASP.NET 的組態設定，讓 HTTP Handler 可以處理特定的副檔名，它可以被視為 .NET Framework 中的 ISAPI Extensions 實作方法。
HTTP Module 則是由 System.Web.IHttpModule 介面定義，它可以在整個網頁生命週期中被呼叫多次，並實際處理由 HttpApplication 所引發的事件，開發人員需要實作 IHttpModule.Init() 方法，以及處理 HttpApplication 事件需要的程式碼。它可被視為 .NET Framework 中的 ISAPI Filter 實作方法。

一致性與多樣性介面的支援　

ASP.NET 在一開始的時候是缺乏範本引擎 (template engine) 的，其主因是.NET Framework本身是物件導向，且需要用繼承的方式才能夠延伸功能，大多數的開發人員都是由 System.Web.UI.Page 繼承並定義出新的基礎類別，並撰寫要繪製 HTML 的方法，以及在他們的應用程式中修改以繼承該類別，然而這個方法可能會被用在網站的很多地方，因而會大大的提升混合程式碼與標記的複雜度，這個方法也只能在執行期才能夠以視覺化的方式測試，無法在設計時期視覺化，其他的開發人員總是使用原有的 ASP 方法（即<!-- #include --> 指令）來把每個網頁需要的部份包到網頁中，防止在每個網頁中都要撰寫相同的導覽程式碼。
在 ASP.NET 2.0 中，推出了母板頁面 (master page)的概念，它可以讓開發人員先行定義外觀版型 (*.master)，再使用它來套用實際執行的網頁，網頁與主版頁面之間以 ContentPlaceHolder 的 ID 做連結，以套用正確的內容到保留區（即由 ContentPlaceHolder 包住的區域）中，開發人員也可以定義在保留區沒有套用時需要顯示的預設內容。在 ASP.NET 3.5 中更進一步的支援設計時期的巢狀主版頁面 (nested master pages)，以及把網頁的 HEAD 區段納入 ContentPlaceHolder 的範圍。
與主版頁面相關的，還有主題(Theme)以及面板(skin)技術，這兩個技術允許開發人員或設計人員自行定義網頁的樣式設定以及套用的樣式支援，每個主題中可以包含數個面板檔，這些面板檔決定了控制項要輸出時套用的樣式，開發人員則可以利用主題來決定不同的外觀要使用的樣式。
ASP.NET 也允許在應用程式中動態的變更主版頁面與主題，但必須要在頁面的 PreInit 事件常式設定。
void Page_PreInit(Object sender, EventArgs e){
    Page.MasterPageFile = "~/NewMaster.master";
    Page.Theme = "MyTheme";}

編譯模型

ASP.NET 在 1.x 時，使用的是組件為主的編譯方式，一個網頁只會產生一個組件，這個方式最大的優點，就是可以自由定義命名空間，且在部署應用程式時會比較方便，但由於 ASP.NET 1.x 所處的時代，如果網站是有許多程式碼的情況下（即 DLL 檔很大），載入的速度會變慢，且佔用記憶體的量會很多，當時的記憶體價格也尚未降到現在的水準。因此在 ASP.NET 2.0 開始，另外提供了一個預先編譯(Pre-compilation) 的編譯模型，這個編譯方法會將每個網頁都各自編譯成一個組件，其檔案名稱會是 App_[亂數字串].dll 命名，在編譯時期由 ASP.NET Pre-compilation 工具（aspnet_compiler.exe）給定，優點是可以不必載入過量的程式碼到記憶體中，但缺點則是無法自訂命名空間，而且在更新時必須要更新所有的 DLL 檔以及網頁等，否則會造成名稱不一致，讓 DLL 無法被載入的問題。
早期 ASP.NET 2.0 僅提供預先編譯模式，讓它的缺點很快的被暴露出來，因此微軟也為 ASP.NET 2.0 開發了沿用 ASP.NET 1.x 的編譯模型的工具：Web Application Project，在 Visual Studio 2008 中開始內建，至此，ASP.NET 支援兩種編譯模式的架構抵定。

安全性支援

ASP.NET 的安全性支援分為驗證 (Authentication)與授權 (Authorization)兩個部份。

Web Service支援

ASP.NET 1.0 開始支援 Web Service 的開發，是微軟在原生平台上支援 Web Service 發展的第一個實作品，但它卻不是微軟的第一個 Web Service 開發工具實作品，.NET Framework 中提供了一個 WSDL.exe，可以連接 Web Service 下載WSDL定義檔，並產生一個 Proxy Class 的原始碼，供用戶端應用程式使用，若是使用 Visual Studio 開發的話，這個動作會由「加入 Web 參考」的動作在背後處理掉。
ASP.NET Web Service 的發展只是平台的基礎，微軟在 Web Service 的開發上提供持續的支援，尤其是在 WS-I (Web Service Interoperability) 組織成立後，為符合 WS-I 的 Web Service 標準，微軟開發了強化 Web Service 的增強套件 Web Service Enhancement (WSE)，最新版本為 3.0 版（搭配 ASP.NET 2.0），可支援許多 WS-I 的標準。
由於 Windows Communication Foundation 的推出，微軟將 Web Service 的發展重心移到 WCF 上，原有的 ASP.NET Web Service 即給定了一個名稱：ASMX Web Service。

擴充功能

ASP.NET 在 2.0 版時，功能已大致底定，成為 Web 應用程式的基礎架構，微軟開始在 ASP.NET 2.0 上開發擴充的功能，包括 AJAX 的支援、MVC架構的支援以及更容易開發出資料庫應用的架構。

ASP.NET AJAX

ASP.NET AJAX 是微軟發展的 AJAX Framework，讓 ASP.NET 的開發人員得以用很簡單的方式就可以開發出支援 AJAX (AJAX-enabled) 的應用程式，包含用戶端指令碼的支援，以及伺服器端的連結等等。

ASP.NET Dynamic Data Framework

ASP.NET Dynamic Data Framework 是微軟在 ASP.NET 3.5 中開發的一組類別庫，封裝在 System.Web.DynamicData 命名空間中，並且配合 ASP.NET Routing Model（網頁繞送功能）讓開發人員可以很簡單的開發出基於 LINQ to SQL 或是 ADO.NET Entity Framework 資料模型的資料庫應用程式。

ASP.NET Routing

ASP.NET Routing Model（官方譯名為 ASP.NET 路由）是一個基於REST規格下的 URL 對應機制，開發人員可以在伺服器端設定 URL 的格式，使用者可以用由開發人員定義的 URL 格式瀏覽網頁，ASP.NET 會自動將 URL 轉換成為內部的 URL 格式，雖然它和 URL Rewriting 很像，但微軟認為 ASP.NET Routing 不是 URL Rewriting。