ASP.NET 4 重大變更
本文件介紹 .NET Framework 版本 4 版本所做的更改,這些更改可能會影響使用早期版本 (包括 ASP.NET 4 Beta 1 和 Beta 2 版本) 建立的應用程式。
目錄
Web.config 檔案中的 ControlRenderingCompatibilityVersion 設定
ClientIDMode 變更
HtmlEncode 和 UrlEncode 現在對單引號進行編碼
ASP.NET 頁面 (.aspx) 剖析器更加嚴格
瀏覽器定義檔已更新
System.Web.Mobile.dll 從根 Web 設定檔中刪除
ASP.NET 請求驗證
預設哈希演算法現為 HMACSHA256
與新 ASP.NET 4 根設定相關的設定錯誤
在 ASP.NET 2.0 或 ASP.NET 3.5 應用程式下,ASP.NET 4 子應用程式無法啟動
ASP.NET 4 網站無法在安裝 SharePoint 的電腦上啟動
HttpRequest.FilePath 屬性不再包含 PathInfo 值
ASP.NET 2.0 應用程式可能會產生參考 eurl.axd 的 HttpException 錯誤
在 IIS 7 或 IIS 7.5 整合模式下,預設文件中可能不會引發事件處理常式
ASP.NET 程式碼存取安全性 (CAS) 實現的更改
MembershipUser 和 System.Web.Security 命名空間中的其他類型已移動
輸出快取更改為 Vary * HTTP 標頭
Passport 的 System.Web.Security 類型已淘汰
MenuItem.PopOutImageUrl 屬性無法在 ASP.NET 4 中轉譯影像
當路徑包含反斜線時,Menu.StaticPopOutImageUrl 和 Menu.DynamicPopOutImageUrl 無法轉譯影像
免責聲明
Web.config 檔案中的 ControlRenderingCompatibilityVersion 設定
ASP.NET 控制項已在 .NET Framework 版本 4 中進行了修改,以便您可以更精確地指定它們轉譯標記的方式。 在 .NET Framework 的早期版本中,某些控制項會發出無法停用的標記。 預設情況下,ASP.NET 4 不再產生此類標記。
如果您使用 Visual Studio 2010 從 ASP.NET 2.0 或 ASP.NET 3.5 升級應用程式,則工具會自動將設定新增至 Web.config
檔案,以保留舊版轉譯。 不過,如果您將 IIS 中的應用程式集區變更成以.NET Framework 4 為目標來升級應用程式,則 ASP.NET 預設會使用新轉譯模式。 若要停用新的轉譯模式,請在 Web.config
檔案中新增下列設定:
<pages controlRenderingCompatibilityVersion="3.5" />
新行為帶來的主要轉譯變化如下:
- Image 和 ImageButton 控制項不再轉譯
border="0"
屬性。 - 預設情況下,BaseValidator 類別和衍生自它的驗證控制項不再轉譯紅色文字。
- HtmlForm 控制項不轉譯名稱屬性。
- Table 控制項不再轉譯
border="0"
屬性。 - 不是為使用者輸入而設計的控制項 (例如,Label 控制項) 如果其 Enabled 屬性設定為 False (或從容器控制項繼承此設定),則不再轉譯
disabled="disabled"
屬性。
ClientIDMode 變更
ASP.NET 4 中的 ClientIDMode 設定可讓您指定 ASP.NET 如何為 HTML 元素產生 id 屬性。 在 ASP.NET 的早期版本中,預設行為相當於 ClientIDMode 的 AutoID 設定。 但是,預設設定現在是可預測的。
如果您使用 Visual Studio 2010 從 ASP.NET 2.0 或 ASP.NET 3.5 升級應用程式,則工具會自動將設定新增至 Web.config
檔案,以保留舊版 .NET Framework 的行為。 不過,如果您將 IIS 中的應用程式集區變更成以.NET Framework 4 為目標來升級應用程式,則 ASP.NET 預設會使用新模式。 若要停用新用戶端 ID 模式,請在 Web.config
檔案中新增下列設定:
<pages clientIDMode="AutoID" />
HtmlEncode 和 UrlEncode 現在對單引號進行編碼
在 ASP.NET 4 中,HttpUtility 和 HttpServerUtility 類別的 HtmlEncode 和 UrlEncode 方法已更新為對單引號字元 (') 進行編碼,如下所示:
- HtmlEncode 方法將單引號的執行個體編碼為 '。
- UrlEncode 方法將單引號的執行個體編碼為 %27。
ASP.NET 頁面 (.aspx) 剖析器更加嚴格
ASP.NET 頁面 (.aspx
檔案) 和使用者控制項 (.ascx
檔案) 的頁面剖析器在 ASP.NET 4 中更加嚴格,並且將拒絕更多無效標記的執行個體。 例如,以下兩個片段在 ASP.NET 的早期版本中可以成功解析,但現在在 ASP.NET 4 中會引發剖析器錯誤。
<asp:HiddenField runat="server" ID="SomeControl" Value="sampleValue" ; />
請注意 HiddenField 標記結尾的無效分號。
<asp:LinkButton runat="server" ID="SomeControl" onclick="someControlClicked"
style="display:inline; CssClass="searchLink" />
請注意 CssClass 屬性中未封閉的 style 屬性。
瀏覽器定義檔已更新
瀏覽器定義檔已更新成包含新增和已更新瀏覽器及裝置的資訊。 已移除 Netscape Navigator 這類較舊的瀏覽器和裝置,並已新增 Google Chrome 和 Apple iPhone 這類較新的瀏覽器和裝置。
如果您的應用程式包含繼承自其中一個已移除瀏覽器定義的自訂瀏覽器定義,則您會看到錯誤。 例如,如果 App_Browsers
資料夾包含從 IE2 瀏覽器定義繼承的瀏覽器定義,您將收到以下設定錯誤訊息:
- 找不到 ID 為「IE2」的瀏覽器或閘道元素。
注意
HttpBrowserCapability 物件 (由頁面的 Request.Browser 屬性公開) 由瀏覽器定義檔驅動。 因此,在 ASP.NET 4 中存取此物件的屬性傳回的資訊,可能與早期版本的 ASP.NET 中傳回的資訊不同。
您可以透過從下列資料夾複製瀏覽器定義檔來還原舊的瀏覽器定義檔:
Windows\Microsoft.NET\Framework\v2.0.50727\CONFIG\Browsers
將檔案複製到 ASP.NET 4 的對應 \CONFIG\Browsers
資料夾中。 在您複製檔案之後,請執行 Aspnet_regbrowsers.exe 命令列工具。
System.Web.Mobile.dll 從根 Web 設定檔中刪除
在 ASP.NET 的早期版本中,對 System.Web.Mobile.dll 組件的參考包含在根 Web.config
檔案中的組件部分中。 為了提高效能,刪除了對此程式集的參考。
System.Web.Mobile.dll 組件包含在 ASP.NET 4 中,但已棄用。 如果要使用 System.Web.Mobile.dll 程式集中的類型,請將此組件的參考新增至根 Web.config
檔案或應用程式 Web.config
檔案。 例如,如果要使用任何 (已棄用的) ASP.NET 行動控制項,則必須將 System.Web.Mobile.dll 組件的參考新增至 Web.config
檔案。
ASP.NET 請求驗證
ASP.NET 中的請求驗證功能提供了一定程度的預設保護,以防止跨站點指令碼 (XSS) 攻擊。 在 ASP.NET 的早期版本中,預設會啟用請求驗證。 但是,它僅適用於 ASP.NET 頁面 (.aspx
檔案及其類別檔案),並且僅適用於這些頁面正在執行的情況。
在 ASP.NET 4 中,預設會對所有請求啟用請求驗證,因為它是在 HTTP 請求的 BeginRequest 階段之前啟用的。 因此,請求驗證適用於所有 ASP.NET 資源的請求,而不僅僅是 .aspx 頁面請求。 這包括 Web 服務呼叫和自訂 HTTP 處理常式等請求。 當自訂 HTTP 模組讀取 HTTP 請求的內容時,請求驗證也會處於作用中狀態。
因此,以前未觸發錯誤的請求現在可能會發生請求驗證錯誤。 若要恢復 ASP.NET 2.0 請求驗證功能的行為,請在 Web.config
檔案中新增以下設定:
<httpRuntime requestValidationMode="2.0" />
但是,我們建議您分析所有請求驗證錯誤,以確定現有處理程序、模組或其他自訂程式碼是否存取可能是 XSS 攻擊媒介的潛在不安全 HTTP 輸入。
預設哈希演算法現為 HMACSHA256
ASP.NET 使用加密和雜湊演算法來協助保護資料,例如表單驗證 Cookie 和檢視狀態。 預設情況下,ASP.NET 4 現在使用 HMACSHA256 演算法對 cookie 和檢視狀態進行雜湊操作。 早期版本的 ASP.NET 使用較舊的 HMACSHA1 演算法。
如果您執行混合 ASP.NET 2.0/ASP.NET 4 環境,其中表單驗證 cookie 等資料必須跨 .NET Framework 版本運作,您的應用程式可能會受到影響。 若要將 ASP.NET 4 Web 應用程式設定為使用較舊的 HMACSHA1 演算法,請在 Web.config
檔案中新增下列設定:
<machineKey validation="SHA1" />
與新 ASP.NET 4 根設定相關的設定錯誤
.NET Framework 4 (以及 ASP.NET 4) 的根設定檔 (machine.config
檔案和根 Web.config
檔案) 已更新,以包含在 ASP.NET 3.5 中在應用程式 Web.config
檔案中找到的大部分樣板設定資訊。 由於託管 IIS 7 和 IIS 7.5 設定系統的複雜性,在 ASP.NET 4 以及 IIS 7 和 IIS 7.5 下執行 ASP.NET 3.5 應用程式可能會導致 ASP.NET 或 IIS 設定錯誤。
如果可行,我們建議您使用 Visual Studio 2010 中的專案升級工具將 ASP.NET 3.5 應用程式升級到 ASP.NET 4。 Visual Studio 2010 會自動修改 ASP.NET 3.5 應用程式的 Web.config
檔案以包含 ASP.NET 4 的適當設定。
但是,使用 .NET Framework 4 執行 ASP.NET 3.5 應用程式而無需重新編譯是支援的方案。 在這種情況下,您可能必須手動修改應用程式的 Web.config
檔案,然後才能在 .NET Framework 4 和 IIS 7 或 IIS 7.5 下執行應用程式。
接下來的兩節描述您可能需要對不同的軟體組合進行的變更。
Windows Vista SP1 或 Windows Server 2008 SP1,未安裝修補程式 KB958854 和 SP2。 在此設定中,IIS 7 設定系統透過將應用程式級 Web.config
檔案與 ASP.NET 2.0 machine.config
檔案進行比較,錯誤地合併了應用程式的託管設定。 因此,.NET Framework 3.5 或更高版本中的應用程式層級 Web.config
檔案必須具有 system.web.extensions 設定節定義 (元素),以免導致 IIS 7 驗證失敗。
但是,手動修改的應用程式層級 Web.config
檔案項目與 Visual Studio 2008 中引入的原始樣板設定節定義不完全相符,將導致 ASP.NET 設定錯誤。 (由 Visual Studio 2008 產生的預設設定項目可以正常運作。) 一個常見的問題是手動修改的 Web.config
檔案遺漏了各種設定節定義中的 allowedDefinition 和 requirePermission 設定屬性。 這會導致應用程式層級 Web.config
檔案中的縮寫設定節與 ASP.NET 4 machine.config
檔案中的完整定義不符。 因此,在執行時,ASP.NET 4 設定系統會引發設定錯誤。
Windows Vista SP2、Windows Server 2008 SP2、Windows 7、Windows Server 2008 R2,以及安裝了修補程式 KB958854 的 Windows Vista SP1 和 Windows Server 2008 SP1。
在這種情況下,IIS 7 和 IIS 7.5 本機設定系統傳回設定錯誤,因為它對託管組態節處理常式定義的 type 屬性執行文字比較。 因為 Visual Studio 2008 和 Visual Studio 2008 SP1 產生的所有 Web.config
檔案在 system.web.extensions (及相關) 設定區段處理常式的類型字串中都具有「3.5」,並且因為 ASP.NET 4 machine.config
檔案具有「4.0」在在同一組態節處理常式的type 屬性中,在Visual Studio 2008 或 Visual Studio 2008 SP1 中產生的應用程式在 IIS 7 和 IIS 7.5 中始終無法透過組態驗證。
解決這些問題
第一種情況的解決方法是透過包含 Visual Studio 2008 自動產生的 Web.config
檔案中的樣板設定文字,來更新應用程式層級 Web.config
檔案。
第一種情況的替代解決方法是在電腦上安裝 Vista 或 Windows Server 2008 的 Service Pack 2,以修復 IIS 設定係統的錯誤設定合併行為。 但是,在執行其中任一操作後,您的應用程式可能會因第二種情況所述的問題而遇到設定錯誤。
第二種情況的解決方法是從應用程式層級 Web.config
檔案中刪除或註解掉所有 system.web.extensions 設定節定義和設定節組定義。 這些定義通常位於應用程式層級 Web.config
檔案的頂部,可以透過 configSections 元素及其子元素來識別。
對於這兩種情況,建議您也手動刪除 system.codedom 部分,儘管這不是必需的。
在 ASP.NET 2.0 或 ASP.NET 3.5 應用程式下,ASP.NET 4 子應用程式無法啟動
因為發生組態或編譯錯誤,所以可能無法啟動設定為執行舊版 ASP.NET 之應用程式子系的 ASP.NET 4 應用程式。 以下範例顯示了受影響的應用程式的目錄結構。
/parentwebapp
(設定為使用 ASP.NET 2.0 或 ASP.NET 3.5)
/childwebapp
(設定為使用 ASP.NET 4)
childwebapp
資料夾中的應用程式將無法在 IIS 7 或 IIS 7.5 上啟動,並報告設定錯誤。 錯誤文字將包含類似以下內容的訊息:
The requested page cannot be accessed because the related configuration data for the page is invalid.
The configuration section 'configSections' cannot be read because it is missing a section declaration.
在 IIS 6 上,childwebapp
資料夾中的應用程式也將無法啟動,但會報告不同的錯誤。 例如,錯誤文字可能會說明以下內容:
The value for the 'compilerVersion' attribute in the provider options must be 'v4.0' or later if you are compiling for version 4.0 or later of the .NET Framework. To compile this Web application for version 3.5 or earlier of the .NET Framework, remove the 'targetFramework' attribute from the element of the Web.config file
出現這些情況的原因是,來自 parentwebapp
資料夾中父應用程式的設定資訊是設定資訊階層的一部分,該階層確定了 childwebapp
資料夾中子 Web 應用程式使用的最終合併設定設定。 根據 ASP.NET 4 Web 應用程式是在 IIS 7 (或 IIS 7.5) 還是 IIS 6 上執行,IIS 設定系統或 ASP.NET 4 編譯系統將傳回錯誤。
解決此問題並使子 ASP.NET 4 應用程式正常運作所必須執行的步驟,取決於 ASP.NET 4 應用程式是在 IIS 6 還是 IIS 7(或 IIS 7.5)上執行。
步驟 1 (僅限 IIS 7 或 IIS 7.5)
僅在執行 IIS 7 或 IIS 7.5 的作業系統 (包括 Windows Vista、Windows Server 2008、Windows 7 和 Windows Server 2008 R2) 上才需要執行此步驟。
將父應用程式 (執行 ASP.NET 2.0 或 ASP.NET 3.5 的應用程式) Web.config
檔案中的 configSections 定義移至 .NET Framework 2.0 的根Web.config
檔案中。 IIS 7 和 IIS 7.5 本機設定系統在合併設定檔的階層時會掃描 configSections 元素。 將 configSections 定義從父 Web 應用程式的 Web.config
檔案移至根 Web.config
檔案可以有效地隱藏子 ASP.NET 4 應用程式所發生的設定合併過程中的元素。
在 32 位元作業系統或 32 位元應用程式集區上,ASP.NET 2.0 和 ASP.NET 3.5 的根Web.config
檔案通常位於下列資料夾中:
C:\Windows\Microsoft.NET\Framework\v2.0.50727\CONFIG
在 64 位元作業系統或 64 位元應用程式集區中,ASP.NET 2.0 和 ASP.NET 3.5 的根 Web.config
檔案通常位於下列資料夾中:
C:\Windows\Microsoft.NET\Framework64\v2.0.50727\CONFIG
如果在 64 位元電腦上同時執行 32 位元和 64 位元 Web 應用程式,則必須將 configSections 元素上移到 32 位元和 64 位元系統的根 Web.config
檔案中。
將 configSections 元素放入根 Web.config
檔案時,將該部分貼到組態元素之後。 以下範例顯示了元素移動完成後根 Web.config
檔案頂部的樣子。
注意
在以下範例中,為了方便閱讀,已將行換行。
<?xml version="1.0" encoding="utf-8"?>
<!-- The root web configuration file -->
<configuration>
<configSections>
<sectionGroup name="system.web.extensions"
type="System.Web.Configuration.SystemWebExtensionsSectionGroup,
System.Web.Extensions, Version=3.5.0.0, Culture=neutral,
PublicKeyToken=31BF3856AD364E35">
<sectionGroup name="scripting"
type="System.Web.Configuration.ScriptingSectionGroup,
System.Web.Extensions, Version=3.5.0.0, Culture=neutral,
PublicKeyToken=31BF3856AD364E35">
<section name="scriptResourceHandler"
type="System.Web.Configuration.ScriptingScriptResourceHandlerSection,
System.Web.Extensions, Version=3.5.0.0, Culture=neutral,
PublicKeyToken=31BF3856AD364E35" requirePermission="false"
allowDefinition="MachineToApplication" />
<sectionGroup name="webServices"
type="System.Web.Configuration.ScriptingWebServicesSectionGroup,
System.Web.Extensions, Version=3.5.0.0, Culture=neutral,
PublicKeyToken=31BF3856AD364E35">
<section name="jsonSerialization"
type="System.Web.Configuration.ScriptingJsonSerializationSection,
System.Web.Extensions, Version=3.5.0.0, Culture=neutral,
PublicKeyToken=31BF3856AD364E35" requirePermission="false"
allowDefinition="Everywhere" />
<section name="profileService"
type="System.Web.Configuration.ScriptingProfileServiceSection,
System.Web.Extensions, Version=3.5.0.0, Culture=neutral,
PublicKeyToken=31BF3856AD364E35" requirePermission="false"
allowDefinition="MachineToApplication" />
<section name="authenticationService"
type="System.Web.Configuration.ScriptingAuthenticationServiceSection,
System.Web.Extensions, Version=3.5.0.0, Culture=neutral,
PublicKeyToken=31BF3856AD364E35" requirePermission="false"
allowDefinition="MachineToApplication" />
<section name="roleService"
type="System.Web.Configuration.ScriptingRoleServiceSection,
System.Web.Extensions, Version=3.5.0.0, Culture=neutral,
PublicKeyToken=31BF3856AD364E35" requirePermission="false"
allowDefinition="MachineToApplication" />
</sectionGroup>
</sectionGroup>
</sectionGroup>
</configSections>
步驟 2 (所有版本的 IIS)
無論 ASP.NET 4 子 Web 應用程式是在 IIS 6 還是 IIS 7 (或 IIS 7.5) 上執行,都需要執行此步驟。
在執行 ASP.NET 2 或 ASP.NET 3.5 的父 Web 應用程式的 Web.config
檔案中,新增一個位置標籤,明確指定 (對於 IIS 和 ASP.NET 設定係統) 設定項目僅適用於父 Web應用。 以下範例顯示了要新增的位置元素的語法:
<location path="" inheritInChildApplications="false" >
<!-- Additional settings -->
</location>
以下範例顯示如何使用位置標籤來包裝從 appSettings 部分開始到 system.webServer 部分結束的所有設定部分。
<location path="" inheritInChildApplications="false" >
<appSettings />
<connectionStrings />
<system.web>
<!-- Removed for brevity -->
</system.web>
<system.codedom>
<!-- Removed for brevity -->
</system.codedom>
<system.webServer>
<!-- Removed for brevity -->
</system.webServer>
</location>
完成步驟 1 和 2 後,子 ASP.NET 4 Web 應用程式將正常啟動。
ASP.NET 4 網站無法在安裝 SharePoint 的電腦上啟動
執行 SharePoint 的 Web 伺服器有一個部署在 SharePoint 網站 (例如,c:\inetpub\wwwroot\web.config
的預設網站) 根目錄的 Web.config
檔案。 在此 Web.config
檔案中,SharePoint 設定名為 WSS_Minimal 的自訂部分信任等級。
如果您嘗試執行作為此類 SharePoint 網站的子網站部署的 ASP.NET 4 網站,您將看到下列錯誤:
Could not find permission set named 'ASP.NET'.
出現此錯誤的原因是 ASP.NET 4 程式碼存取安全性 (CAS) 基礎結構尋找名為 ASP.NET 的權限集。 但是,WSS_Minimal 所參考的部分信任設定檔不包含任何具有該名稱的權限集。
目前沒有與 ASP.NET 相容的 SharePoint 版本。 因此,您不應嘗試將 ASP.NET 4 網站作為 SharePoint 網站下的子網站運作。
HttpRequest.FilePath 屬性不再包含 PathInfo 值
早期版本的 ASP.NET 在從各種檔案路徑相關屬性 (包括 HttpRequest.FilePath、HttpRequest.AppRelativeCurrentExecutionFilePath 和 HttpRequest.CurrentExecutionFilePath) 傳回的值中包含 PathInfo 值。 ASP.NET 4 不再在這些屬性的回傳值中包含 PathInfo 值。 相反,PathInfo 資訊在 HttpRequest.PathInfo 中可用。 例如,假設有下列 URL 片段:
/testapp/Action.mvc/SomeAction
在早期版本的 ASP.NET 中,HttpRequest 屬性具有下列值:
HttpRequest.FilePath:/testapp/Action.mvc/SomeAction
HttpRequest.PathInfo:(空)
在 ASP.NET 4 中,HttpRequest 屬性具有下列值:
HttpRequest.FilePath:/testapp/Action.mvc
HttpRequest.PathInfo:SomeAction
ASP.NET 2.0 應用程式可能會產生參考 eurl.axd 的 HttpException 錯誤
在 IIS 6 上啟用 ASP.NET 4 之後,IIS 6 上執行的 ASP.NET 2.0 應用程式 (在 Windows Server 2003 或 Windows Server 2003 R2 中) 可能會產生下列這類錯誤:
System.Web.HttpException: Path '/[yourApplicationRoot]/eurl.axd/[Value]' was not found.
發生此錯誤的原因是,當 ASP.NET 偵測到網站設定為使用 ASP.NET 4 時,ASP.NET 4 的本機元件會將無副檔名的URL 傳遞到 ASP.NET 的託管部分以進行進一步處理。 但是,如果將 ASP.NET 4 網站下面的虛擬目錄設定為使用 ASP.NET 2.0,則以這種方式處理無副檔名 URL 會導致包含字串「eurl.axd」的修改後的 URL。 然後將此修改後的 URL 傳送到 ASP.NET 2.0 應用程式。 ASP.NET 2.0 無法辨識「eurl.axd」格式。 因此,ASP.NET 2.0 嘗試尋找名為 eurl.axd
的檔案並執行它。 由於不存在此類文件,因此請求失敗並出現 HttpException 例外狀況。
您可以使用以下選項之一解決此問題。
選項 1
如果執行網站不需要 ASP.NET 4,請重新對應網站以使用 ASP.NET 2.0。
選項 2
如果需要 ASP.NET 4 才能運作網站,請將任何子 ASP.NET 2.0 虛擬目錄移至對應到 ASP.NET 2.0 的其他網站。
選項 3
如果將網站重新對應到 ASP.NET 2.0 或變更虛擬目錄的位置不切實際,請在 ASP.NET 4 中明確停用無副檔名 URL 處理。 請使用下列程序:
- 在 Windows 登錄中,開啟下列節點:
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\ASP.NET\4.0.30319.0
- 建立一個名為 EnableExtensionlessUrls 的新 DWORD 值。
- 將 EnableExtensionlessUrls 設定為 0。 這將停用無擴充 URL 行為。
- 儲存登錄值並關閉登錄編輯器。
- 執行 iisreset 命令列工具,這會導致 IIS 讀取新的登錄值。
注意
將 EnableExtensionlessUrls 設定為 1 可啟用無擴充 URL 行為。 如果未指定值,則這是預設值。
在 IIS 7 或 IIS 7.5 整合模式下,預設文件中可能不會引發事件處理常式
ASP.NET 4 包含一些修改,這些修改會變更當無副檔名 URL 解析為預設文件時 HTML 表單元素的 action 屬性的轉譯方式。 解析為預設文件的無副檔名 URL 的一個範例是 http://contoso.com/
,導致對 http://contoso.com/Default.aspx
的請求。
現在,當向對應了預設文件的無擴充 URL 發出請求時,ASP.NET 4 將 HTML 表單元素的 action 屬性值轉譯為空字串。 例如,在 ASP.NET 的早期版本中,對 http://contoso.com
的請求將導致對 Default.aspx
的請求。 在該文件中,將轉譯開啟表單標籤,如下例所示:
<form action="Default.aspx" />
在 ASP.NET 4 中,對 http://contoso.com
的請求也會導致對 Default.aspx
的請求。 但是,ASP.NET 現在轉譯 HTML 開啟表單標籤,如下例所示:
<form action="" />
action 屬性轉譯方式的這種差異可能會導致 IIS 和 ASP.NET 處理表單發佈的方式發生細微變化。 當 action 屬性為空字串時,IIS DefaultDocumentModule 物件將建立一個對 Default.aspx
的子請求。 在大部分的情況下,應用程式碼可以辨識此子請求,Default.aspx
頁面則會正常執行。
不過,Managed 程式碼與 IIS 7 或 IIS 7.5 整合模式之間的可能互動可能會在子要求期間讓受管理 .aspx 頁面適當地停止運作。 如果發生以下情況,對 Default.aspx
文件的子請求將導致錯誤或未預期的行為:
- 將 .aspx 頁面傳送到瀏覽器,並將表單元素的 action 屬性設為「」。
- 該表單被傳回 ASP.NET。
- 託管 HTTP 模組讀取實體主體的某些部分。 例如,模組讀取 Request.Form 或 Request.Params。 這會將 POST 要求的實體主體讀入受管理記憶體中。 因此,任何以 IIS 7 或 IIS 7.5 整合模式執行的機器碼模組都無法再使用實體主體。
- IIS DefaultDocumentModule 物件最終執行並建立對
Default.aspx
文件的子請求。 不過,因為 Managed 程式碼的某個部分已經讀取實體主體,所以沒有實體主體可用來傳送至子要求。 - 當 HTTP 管線針對子請求執行時,
.aspx
檔案處理常式會在處理常式執行階段執行。 - 由於沒有實體主體、表單變數和檢視狀態,因此 .aspx 頁面處理常式沒有可用資訊來確定應該引發什麼事件 (如果有)。 因此,未執行受影響 .aspx 頁面的回傳事件處理常式。
您可以透過以下方式解決此問題:
識別在預設文件請求期間存取請求實體本文的 HTTP 模組,並確定是否可以將其設定為僅針對託管請求執行。 在 IIS 7 和 IIS 7.5 的整合模式下,透過將下列屬性新增至模組的 system.webServer/modules 項目,可以將 HTTP 模組標記為僅針對託管請求執行:
precondition="managedHandler"
此設定針對 IIS 7 和 IIS 7.5 確定為非託管請求的請求停用該模組。 對於預設文件請求,第一個請求是無副檔名的 URL。 因此,在初始請求處理期間,IIS 不會執行任何標記有託管處理常式前提條件的託管模組。 因此,託管模組不會意外讀取實體主體,因此實體主體仍然可用,並傳遞到子請求和預設文件。
如果有問題的 HTTP 模組必須對所有請求 (例如靜態檔案、解析為 DefaultDocumentModule 物件、受管理的請求等) 執行,則需要通過明確將頁面的 Action 屬性設定為非空字串來修改受影響的 .aspx 頁面,這樣可以在 System.Web.UI.HtmlControls.HtmlForm 控制項中進行設定。 例如,如果預設文件是
Default.aspx
,請修改頁面的程式碼以將 HtmlForm 控制項的 Action 屬性明確設定為「Default.aspx」。
ASP.NET 程式碼存取安全性 (CAS) 實現的更改
ASP.NET 2.0 以及 3.5 中新增的 ASP.NET 功能擴充功能使用 .NET Framework 1.1 和 2.0 程式碼存取安全性 (CAS) 模型。 不過,已大幅全面檢查 ASP.NET 4 中 CAS 的實作。 因此,如果部分信任 ASP.NET 應用程式依賴在全域組件快取 (GAC) 中執行的受信任程式碼,則可能會因各種安全性例外狀況而失敗。 依賴對電腦 CAS 策略進行大量修改的部分信任應用程式也可能會因安全性例外狀況而失敗。
在 trust 組態元素中使用新 legacyCasModel 屬性,即可將部分信任 ASP.NET 4 應用程式還原為 ASP.NET 1.1 和 2.0 的行為,如下列範例所示:
<trust level= "Medium" legacyCasModel="true" />
當您恢復到舊 CAS 模型時,將啟用以下舊 CAS 行為:
- 遵守機器 CAS 政策。
- 允許在單一應用程式網域中設定多個不同的權限集。
- 當堆疊上只有 ASP.NET 或其他 .NET Framework 程式碼時所呼叫的 GAC 中的組件不需要明確權限斷言。
.NET Framework 4 中無法還原一種情況:非 Web 部分信任應用程式無法再呼叫 System.Web.dll 和 System.Web.Extensions.dll 中的某些 API。 在 .NET Framework 的早期版本中,可以明確地授予非 Web 部分信任應用程式 AspNetHostingPermission 權限。 然後,這些應用程式可以使用 System.Web.HttpUtility、System.Web.ClientServices.* 命名空間中的類型以及與成員資格、角色和設定檔相關的類型。 .NET Framework 4 不再支援從非 Web 部分信任應用程式呼叫這些類型。
注意
System.Web.HttpUtility 類別的 HtmlEncode 和 HtmlDecode 功能已移至新的 .NET Framework 4 System.Net.WebUtility 類別。 如果這是正在使用的唯一 ASP.NET 功能,請修改應用程式的程式碼以使用新的 WebUtility 類別。
以下是 ASP.NET 4 中預設 CAS 實作變更的進階摘要:
- ASP.NET 應用程式網域現在是同類應用程式網域。 應用程式網域中僅提供部分信任和完全信任授權集。
- ASP.NET 部分信任授權集獨立於任何企業級、機器級或使用者級 CAS 策略。
- 3.5 和 3.5 SP1 中隨附的 ASP.NET 組件已轉換為使用 .NET Framework 4 透明度模型。
- ASP.NET AspNetHostingPermission 屬性的使用已大幅減少。 此屬性的大多數執行個體已從公用 ASP.NET API 中刪除。
- 由 ASP.NET 產生提供者建立的動態編譯的組件已更新為將組件明確標記為透明。
- 現在,所有 ASP.NET 組件都以僅在 Web 託管環境中遵循 APTCA 屬性的方式進行標記。 部分受信任的非 Web 託管環境 (例如 ClickOnce) 將無法呼叫 ASP.NET 組件。
有關新的 ASP.NET 4 程式碼存取安全模型的詳細資訊,請參閱 MSDN 網站上的在 ASP.NET 應用程式中使用程式碼存取安全性。
MembershipUser 和 System.Web.Security 命名空間中的其他類型已移動
ASP.NET 成員資格中使用的某些類型已從 System.Web.dll
移至 System.Web.ApplicationServices.dll 組件。 已移動類型,以解析用戶端和擴充 .NET Framework SKU 中類型之間的架構層相依性。
網站專案不會因移動這些類型而出現問題,因為 System.Web.ApplicationServices.dll 已新增至 ASP.NET 編譯系統預設使用的參考組件清單中。 如果透過在 Visual Studio 2010 中開啟使用早期版本的 ASP.NET 建立的網站專案將其升級到 ASP.NET 4,則該專案將正確編譯。
同樣,如果透過在Visual Studio 2010 中開啟在早期版本的ASP.NET 中建立的Web 應用程式專案將其升級到ASP.NET 4,則升級過程會將System.Web.ApplicationServices.dll 的參考新增至該項目中。 因此,升級後的 Web 應用程式專案也將正確編譯。
使用早期版本的 ASP.NET 建立的編譯 (二進位) 檔案也將在 ASP.NET 4 上執行,不會出現錯誤,即使成員資格類型已移至不同的組件。 類型轉送資訊已新增至 System.Web.dll
的 ASP.NET 4 版本中,自動將這些類型的執行時間參考路由到類型的新位置。
但是,使用特定成員資格類型並且從早期版本的 ASP.NET 升級的類別庫在 ASP.NET 4 專案中使用時將無法編譯。 例如,類別庫專案可能無法編譯並報告以下錯誤:
The type 'System.Web.Security.MembershipUser' is defined in an assembly that is not referenced. You must add a reference to assembly 'System.Web.ApplicationServices, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35'.
The type name 'MembershipUser' could not be found. This type has been forwarded to assembly 'System.Web.ApplicationServices, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35'. Consider adding a reference to that assembly.
您可以透過在類別庫專案中新增對 System.Web.ApplicationServices.dll 的參考來解決此問題。
以下清單顯示了已從 System.Web.dll
移至 System.Web.ApplicationServices.dll 的 System.Web.Security 類型:
- System.Web.Security.MembershipCreateStatus
- System.Web.Security.Membership.CreateUserException
- System.Web.Security.MembershipPasswordException
- System.Web.Security.MembershipPasswordFormat
- System.Web.Security.MembershipProvider
- System.Web.Security.MembershipProviderCollection
- System.Web.Security.MembershipUser
- System.Web.Security.MembershipUserCollection
- System.Web.Security.MembershipValidatePasswordEventHandler
- System.Web.Security.ValidatePasswordEventArgs
- System.Web.Security.RoleProvider
- System.Web.Configuration.MembershipPasswordCompatibilityMode
輸出快取更改為 Vary * HTTP 標頭
在 ASP.NET 1.0 中,一個錯誤導致指定 Location="ServerAndClient"
作為輸出快取設定的快取頁面在回應中發出 Vary:*
HTTP 標頭。 這會影響如何告知用戶端瀏覽器永遠不要在本機快取頁面。
在 ASP.NET 1.1 中,新增了 System.Web.HttpCachePolicy.SetOmitVaryStar 方法,您可以呼叫該方法來隱藏 Vary:*
標頭。 選擇此方法是因為更改發出的 HTTP 標頭在當時被認為是潛在的重大變更。 然而,開發人員對 ASP.NET 中的行為感到困惑,並且錯誤報告表明開發人員不知道現有的 SetOmitVaryStar 行為。
在 ASP.NET 4 中,我們決定解決根本問題。 指定以下指令的回應不再發出 Vary:*
HTTP 標頭:
<%@OutputCache Location="ServerAndClient" %>
因此,不再需要 SetOmitVaryStar 來隱藏 Vary:*
標頭。
在頁面上的 @OutputCache 指令中指定 Location="ServerAndClient"
的應用程式中,您現在將看到 Location 屬性值的名稱所隱含的行為 - 即,頁面將可在瀏覽器中快取,而無需您呼叫 SetOmitVaryStar 方法。
如果應用程式中的頁面必須發出 Vary:*
,請呼叫 AppendHeader 方法,如下例所示:
HttpResponse.AppendHeader("Vary","*");
或者,您可以將輸出快取 Location 屬性的值變更為「伺服器」。
Passport 的 System.Web.Security 類型已淘汰
由於 Passport (現在的 LiveID) 的變化,ASP.NET 2.0 中內建的 Passport 支援已經淘汰並且在幾年內不受支援。 因此,System.Web.Security 中與 Passport 相關的五種類型現在使用 ObsoleteAttribute 屬性進行標記。
MenuItem.PopOutImageUrl 屬性無法在 ASP.NET 4 中轉譯影像
在 ASP.NET 3.5 中,MenuItem.PopOutImageUrl 屬性可讓您指定功能表項目中顯示的影像的 URL,以指示該功能表項目具有動態子功能表。 以下範例示範如何在 ASP.NET 3.5 的標籤中指定此屬性。
<asp:menu id="NavigationMenu"
staticdisplaylevels="1"
staticsubmenuindent="10"
orientation="Vertical"
target="_blank"
runat="server">
<items>
<asp:menuitem navigateurl="default2.aspx"
text="Home"
PopOutImageUrl="~/Images/Popout.gif"
tooltip="Home">
<asp:menuitem navigateurl="default3.aspx"
text="Movies"
PopOutImageUrl="~/Images/Popout.gif"
tooltip="Movies">
</asp:menuitem>
</asp:menuitem>
</items>
</asp:menu>
由於 ASP.NET 4 中的設計更改,如果為 MenuItem 類別設定該屬性,則不會為 PopOutImageUrl 轉譯任何輸出。 相反,您必須使用 StaticPopOutImageUrl 屬性或 DynamicPopOutImageUrl 屬性直接在 Menu 控制項中指定影像 URL。 使用靜態功能表時,Menu.StaticPopOutImageUrl 屬性指定顯示影像的 URL,以指示靜態功能表項目具有子功能表,如以下範例所示:
<asp:menu id="NavigationMenu"
staticdisplaylevels="1"
staticsubmenuindent="10"
orientation="Vertical"
target="_blank"
StaticPopOutImageTextFormatString="More..."
StaticPopOutImageUrl="Images/Popout.gif"
runat="server">
<items>
<asp:menuitem navigateurl="default2.aspx"
text="Home"
tooltip="Home">
<asp:menuitem navigateurl="default3.aspx"
text="Movies"
tooltip="Movies">
</asp:menuitem>
</asp:menuitem>
</items>
</asp:menu>
如果您使用動態功能表,則可以使用 Menu.DynamicPopOutImageUrl 屬性指定指示動態功能表項目具有子功能表的圖片的 URL。 以下範例與上一個範例類似,但顯示如何設定動態功能表的 DynamicPopOutImageUrl 屬性。
<asp:menu id="NavigationMenu"
staticdisplaylevels="1"
staticsubmenuindent="10"
orientation="Vertical"
target="_blank"
DynamicPopOutImageTextFormatString="More..."
DynamicPopOutImageUrl="Images/Popout.gif"
runat="server">
<items>
<asp:menuitem navigateurl="default2.aspx"
text="Home"
tooltip="Home">
<asp:menuitem navigateurl="default3.aspx"
text="Movies"
tooltip="Movies">
</asp:menuitem>
</asp:menuitem>
</items>
</asp:menu>
如果未設定 Menu.DynamicPopOutImageUrl 屬性且 Menu.DynamicEnableDefaultPopOutImage 屬性設為 False,則不會顯示任何影像。 同樣,如果未設定 StaticPopOutImageUrl 屬性並且將 StaticEnableDefaultPopOutImage 屬性設為 False,則不會顯示任何影像。
設定這些屬性的路徑時,請使用正斜線 (/) 而不是反斜線 ()。 有關詳細資訊,請參閱本文件中關於 Menu.StaticPopOutImageUrl 和 Menu.DynamicPopOutImageUrl 在路徑包含反斜線時無法轉譯影像的部分。
當路徑包含反斜線時,Menu.StaticPopOutImageUrl 和 Menu.DynamicPopOutImageUrl 無法轉譯影像
在 ASP.NET 4 中,如果路徑包含反斜線 (),則使用 Menu.StaticPopOutImageUrl 和 Menu.DynamicPopOutImageUrl 屬性指定的影像將不會轉譯。 這是對 ASP.NET 早期版本的變更。
以下 Menu 控制項標記範例顯示了使用包含反斜線的路徑設定的 StaticPopOutImageUrl 屬性。 在 ASP.NET 4 中,屬性中指定的影像將不會轉譯。
<asp:menu id="NavigationMenu"
staticdisplaylevels="1"
staticsubmenuindent="10"
orientation="Vertical
target="_blank"
StaticPopOutImageTextFormatString="More..."
StaticPopOutImageUrl="Images\Popout.gif"
runat="server">
<items>
<asp:menuitem navigateurl="default2.aspx"
text="Home"
tooltip="Home">
<asp:menuitem navigateurl="default3.aspx"
text="Movies"
tooltip="Movies">
</asp:menuitem>
</asp:menuitem>
</items>
</asp:menu>
若要修正此問題,請將 StaticPopOutImageUrl 和 DynamicPopOutImageUrl 屬性中指定的路徑值變更為使用正斜線 (/)。 以下範例顯示了此變更:
<asp:menu id="NavigationMenu"
staticdisplaylevels="1"
staticsubmenuindent="10"
orientation="Vertical
target="_blank"
StaticPopOutImageTextFormatString="More..."
StaticPopOutImageUrl="Images/Popout.gif"
runat="server">
<items>
<asp:menuitem navigateurl="default2.aspx"
text="Home"
tooltip="Home">
<asp:menuitem navigateurl="default3.aspx"
text="Movies"
tooltip="Movies">
</asp:menuitem>
</asp:menuitem>
</items>
</asp:menu>
請注意,從早期版本的 ASP.NET 遷移到 ASP.NET 4 的應用程式也可能會受到影響,因為 MenuItem.PopOutImageUrl 屬性已變更。 有關詳細資訊,請參閱本文件中關於 MenuItem.PopOutImageUrl 屬性在 ASP.NET 4 中無法轉譯影像的部分。
免責聲明
這是一份初稿,內容在本文所述的軟體於正式商業發行前都可能有所更動。
本文件包含的資訊代表 Microsoft Corporation 對於截至文件發行當日為止探討之問題的最新觀點。 由於 Microsoft 必須回應不斷變動的市場狀況,因此您不應該將這些觀點解讀成 Microsoft 所做的承諾,而且 Microsoft 也無法保證發行日期後提出之任何資訊的正確性。
本技術白皮書僅供參考。 MICROSOFT 對本文件中的資訊不提供任何明示、暗示或法定擔保。
遵守所有適用之著作權法係使用者的責任。 在不影響著作權法律所賦予權利之情況下,未經 Microsoft Corporation 明示書面許可,不得將本文件任何部分重製、儲存或引進檢索系統,或以任何形式、任何方式 (電子、機械、影印、錄音或其他方式) 或因任何目的進行傳輸。
Microsoft 對本文件所述及之主題可能擁有專利權、申請中專利權、商標權、著作權或其他智慧財產權。 除非 Microsoft 書面授權合約中所明示規定者外,提供本文件並不授予 貴用戶上述專利權、商標、著作權或其他智慧財產權。
除非另有說明,本文描述的範例公司、組織、產品、網域、電子郵件地址、徽標、人員、地點和事件都是虛構的,與任何真實的公司、組織、產品、網域名稱、電子郵件地址、徽標、人、地點或事件是有意的或應該推斷的。
© 2010 Microsoft Corporation. 著作權所有,並保留一切權利。
Microsoft 和 Windows 是 Microsoft Corporation 在美國及/或其他國家/地區的註冊商標或商標。
本文件中所提實際公司和產品名稱,可能為各所有人所有之商標。