共用方式為


ASP.NET Web Forms的 URL 重寫

作者: Ruslan Yakushev

當您搭配使用 IIS URL 重寫模組搭配 ASP.NET 應用程式時,請務必確保 Web 應用程式具有重寫 URL 的正確行為。 本文說明 URL 重寫可能會影響 ASP.NET Web 應用程式的案例,以及潛在問題的解決方案。

目錄

設定 Form 元素的回傳 URL

ASP.NET Web Forms大量使用回傳,這讓執行 ASP.NET 網頁的 URL 重寫有點棘手。 如果頁面包含一或多個網頁伺服器控制項,則當 ASP.NET 轉譯頁面時,它會設定 HTML 表單專案的動作屬性,以指向表單元素所在的頁面,也就是它指向本身。 如果 URL 重寫用於該頁面,動作屬性會指向重寫的 URL,而不是從瀏覽器要求的 URL。 這會導致瀏覽器在發生回傳時,在位址方塊中顯示重寫的 URL。

若要防止動作屬性指向錯誤的 URL,您可以將頁面上 HtmlForm 實例的 Action 屬性設定為瀏覽器所要求的回傳 URL。 您可以使用 HttpRequest.RawUrl 屬性,從 取得該 URL。 下列範例示範如何修改 ASP.NET 網頁來設定動作 URL。

protected void Page_Load(object sender, EventArgs e) 
{ 
    form1.Action = Request.RawUrl; 
}

注意

HtmlForm.Action 屬性可從 .NET Framework 3.5 版 SP1 開始取得。

如果您使用 ASP.NET 主版頁面,您可以將程式碼新增至主版頁面的 Page_Load 方法,以設定使用該主版頁面的所有頁面回傳動作 URL。

重寫 AJAX UpdatePanel 控制項的 URL

當您使用 URL 重寫模組來重寫包含一或多個 UpdatePanel 控制項之頁面的 URL 時,控制項會針對該 UpdatePanel 控制項所執行的所有動作使用重寫 URL。 這可能會導致 UpdatePanel 控制項中的控制項無法正確運作,特別是在 URL 重寫變更所要求 URL 的目錄階層時。 例如,如果您使用 URL 重寫模組將 /Products/Hardware 重寫為 /Products.aspx,UpdatePanel 控制項會針對 UpdatePanel 控制項內的所有動作使用 URL /Products/Hardware/Products.aspx。 這會導致腳本錯誤。

若要避免發生這種情況,請設定頁面 HtmlForm 實例的 Action 屬性,如上一節中 設定 Form 元素的回傳 URL 中所述。

在 Web 服務器控制項中使用 ~ 運算子

當您需要設定路徑時,您可以使用 ASP.NET Web 服務器控制項中的 ~ 運算子來參考應用程式目錄的根目錄。 不過,如果 URL 重寫變更所要求 URL 的目錄階層,這可能會導致以 ~ 運算子指定的連結無法正確解析。 例如,假設名為 app1 之 Web 應用程式根目錄的 Default.aspx 頁面包含下列影像控制項:

<asp:Image runat="server" ImageUrl="~/Images/MyImage.gif" />

如果 URL 重寫會將 URL 從 http://localhost/app1/folder/file 變更為 http://localhost/app1/default.aspx ,則以 ~ 運算子指定的連結將會相對於重寫的 URL 路徑解析,這會相對於 /app1 資料夾。 下列範例顯示 img 元素產生的 HTML 標籤:

<img src="Images/MyImage.gif" ... >

因為瀏覽器要求 http://localhost/app1/folder/file ,所以它會嘗試從 http://localhost/app1/folder/Images/MyImage.gif 取得影像。 這會導致 404 (找不到檔案) 錯誤。

IIS 的 URL 重寫模組包含修正此行為的 ASP.NET 更新。 更新會導致 Web 服務器控制項中的 ~ 運算子相對於原始要求的 URL 進行解析。 在上述範例中,回應中的 HTML 標籤將包含 img 元素的正確 URL 路徑,如下列標記所示:

<img src="../Images/MyImage.gif" ... >

ASP.NET 的更新僅適用于 .NET Framework 3.5 SP1 和更新版本。 若要取得更新,請將.NET Framework升級至 3.5 SP1 版,然後執行 IIS URL 重寫模組安裝程式,以安裝 ASP.NET 更新。

重寫 URL 和網站導覽控制項

ASP.NET 網站地圖可用來描述網站的結構,讓網站導覽 API 和網站導覽控制項可以公開邏輯 (,而不是實體) 網站結構。 當您搭配使用 URL 重寫模組與使用網站導覽的 ASP.NET 應用程式時,通常希望導覽控制項以使用公用或虛擬 URL 的邏輯網站結構運作。

例如,您可以定義網站地圖,如下列範例所示:

<?xml version="1.0" encoding="utf-8" ?>
<siteMap xmlns="http://schemas.microsoft.com/AspNet/SiteMap-File-1.0">
  <siteMapNode url="~/Products/" title="Products" description="Products Home Page">   
    <siteMapNode url="~/Products/Hardware/" title="Hardware" description="Hardware Products" /> 
    <siteMapNode url="~/Products/Software/" title="Software" description="Software Products" />
  </siteMapNode>
</siteMap>

然後,您可以定義執行下列重寫的重寫規則:

  • /Products/ 至 /Products.aspx
  • /Products/Hardware to /Products.aspx?category=Hardware
  • /Products/Software to /Products.aspx?category=Software

使用這些虛擬 URL 定義網站地圖可能會導致 SystemWeb.SiteMap 類別無法正常運作。 當您嘗試在 ASP.NET 網頁中存取 SiteMap.CurrentNode 屬性時,屬性可能包含 null。 這可能會導致 SiteMapPath 和 Menu 之類的網站導覽控制項無法正常運作。

IIS 的 URL 重寫模組包含 ASP.NET 的更新,可修正導覽控制項,讓它們能夠使用重寫的虛擬 URL。 透過此更新,SiteMap.CurrentNode 屬性會參考對應至目前要求的虛擬 URL 的 SiteMapNode。

ASP.NET 的更新僅適用于 .NET Framework 3.5 SP1 和更新版本。 若要取得更新,請將.NET Framework升級至 3.5 SP1 版,然後執行 IIS URL 重寫模組安裝程式,以安裝 ASP.NET 更新。

防止重寫 ASP.NET Web 資源的要求

ASP.NET 型 Web 應用程式經常對 WebResources.axd 檔案提出要求,以擷取元件資源並將其提供給網頁瀏覽器。 伺服器上沒有這類檔案,因為 ASP.NET 要求 WebResources.axd 時動態產生內容。 因此,如果您的 URL 重寫規則只有在要求的 URL 未對應至網頁伺服器的檔案系統上的檔案或資料夾時,才進行重寫或重新導向的 URL 重寫規則,該規則可能會意外重寫對 WebResources.axd 提出的要求,因而中斷您的應用程式。

如果您將一個額外的條件新增至重寫規則,就可以輕鬆地防止此問題:

<rule name="RewriteUserFriendlyURL1" stopProcessing="true">
  <match url="^([^/]+)/?$" />
  <conditions>
    <add input="{REQUEST_FILENAME}" matchType="IsFile" negate="true" />
    <add input="{REQUEST_FILENAME}" matchType="IsDirectory" negate="true" />
    <!--  The following condition prevents rule from rewriting requests to .axd files -->
    <add input="{URL}" negate="true" pattern="\.axd$" />
  </conditions>
  <action type="Rewrite" url="article.aspx?p={R:1}" />
</rule>