ASP.NET 4 重大更改

本文档介绍对.NET Framework版本 4 版本所做的更改,这些更改可能会影响使用早期版本(包括 ASP.NET 4 Beta 1 和 Beta 2 版本)创建的应用程序。

下载此白皮书

目录

Web.config 文件中的 ControlRenderingCompatibilityVersion 设置
ClientIDMode 更改
HtmlEncode 和 UrlEncode 现在对单引号进行编码
ASP.NET Page (.aspx) 分析程序更严格
已更新浏览器定义文件
根 Web 配置文件中删除_Toc256770146System.Web.Mobile.dll
ASP.NET 请求验证
默认哈希算法现在为 HMACSHA256
与新 ASP.NET 4 根配置相关的配置错误
ASP.NET 4 个子应用程序在 ASP.NET 2.0 或 ASP.NET 3.5 应用程序下无法启动
ASP.NET 4 个网站无法在安装了 SharePoint 的计算机上启动
HttpRequest.FilePath 属性不再包含 PathInfo 值
ASP.NET 2.0 应用程序可能会生成引用 eurl.axd 的 HttpException 错误
在 IIS 7 或 IIS 7.5 集成模式下,可能不会在默认文档中引发事件处理程序
对 ASP.NET 代码访问安全性 (CAS) 实现的更改
已移动 System.Web.Security 命名空间中的 MembershipUser 和其他类型
输出缓存更改以更改 * 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" />

新行为带来的主要呈现更改如下所示:

  • ImageImageButton 控件不再呈现border="0"属性。
  • 默认情况下,派生自它的 BaseValidator 类和验证控件不再呈现红色文本。
  • HtmlForm 控件不呈现名称属性。
  • Table 控件不再呈现border="0"属性。
  • 例如,不设计用于用户输入的控件 (,如果标签控件的Enabled 属性设置为 false (或从容器控件) 继承此设置,则标签控件) 不再呈现disabled="disabled"属性。

ClientIDMode 更改

ASP.NET 4 中的 ClientIDMode 设置可用于指定 ASP.NET 如何为 HTML 元素生成 id 属性。 在早期版本的 ASP.NET 中,默认行为等效于 ClientIDModeAutoID 设置。 但是,默认设置现在是 可预测的

如果使用 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 中,HttpUtilityHttpServerUtility 类的 HtmlEncodeUrlEncode 方法已更新,以将单引号字符编码 (') ,如下所示:

  • HtmlEncode 方法将单引号的实例编码为 ' 。
  • UrlEncode 方法将单引号的实例编码为 %27。

ASP.NET Page (.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 属性中的未封闭样式属性。

已更新浏览器定义文件

浏览器定义文件已更新,以包括有关新的和已更新的浏览器和设备的信息。 旧式浏览器和设备(如 Netscape Navigator)已被删除,并且已添加更新的浏览器和设备(如 Google Chrome 和 Apple iPhone)。

如果应用程序包含的自定义浏览器定义继承自一个已删除的浏览器定义,将会出现错误。 例如,如果 App_Browsers 文件夹包含继承自 IE2 浏览器定义的浏览器定义,则会收到以下配置错误消息:

  • 找不到 ID 为“IE2”的浏览器或网关元素。

注意

HttpBrowserCapabilities 对象 (,该对象由页面的 Request.Browser 属性) 由浏览器定义文件驱动。 因此,在 ASP.NET 4 中通过访问此对象的属性返回的信息可能与 ASP.NET 早期版本中返回的信息不同。

可以通过从以下文件夹复制浏览器定义文件来还原旧浏览器定义文件:

Windows\Microsoft.NET\Framework\v2.0.50727\CONFIG\Browsers

将文件复制到 ASP.NET 4 的相应 \CONFIG\Browsers 文件夹中。 复制这些文件之后,请运行 Aspnet_regbrowsers.exe 命令行工具。

从根 Web 配置文件中删除System.Web.Mobile.dll

在早期版本的 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" />

但是,建议分析任何请求验证错误,以确定现有处理程序、模块或其他自定义代码是否访问可能不安全的 HTTP 输入(可能是 XSS 攻击途径)。

默认哈希算法现在为 HMACSHA256

ASP.NET 使用加密算法和哈希算法来帮助保护数据(如窗体身份验证 Cookie 和视图状态)。 默认情况下,ASP.NET 4 现在使用 HMACSHA256 算法对 Cookie 和视图状态执行哈希操作。 早期版本的 ASP.NET 使用较旧的 HMACSHA1 算法。

如果运行混合 ASP.NET 2.0/ASP.NET 4 环境,其中表单身份验证 cookie 等数据必须 across.NET 框架版本工作,应用程序可能会受到影响。 若要将 ASP.NET 4 Web 应用程序配置为使用较旧的 HMACSHA1 算法,请在 文件中添加以下设置 Web.config

<machineKey validation="SHA1" />

根配置文件 (machine.config文件和.NET Framework 4 (的根Web.config文件) ,因此 ASP.NET 4) 已更新,以包含 ASP.NET 3.5 中在应用程序Web.config文件中找到的大多数样板配置信息。 由于托管的 IIS 7 和 IIS 7.5 配置系统的复杂性,在 ASP.NET 4 和 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 应用程序而不重新编译是受支持的方案。 在这种情况下,在.NET Framework 4 和 IIS 7 或 IIS 7.5 下运行应用程序之前,可能需要手动修改Web.config应用程序的文件。

接下来的两个部分介绍可能需要对不同软件组合进行的更改。

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 的文件忽略了各种配置节定义上的 allowDefinitionrequirePermission 配置属性。 这会导致应用程序级别 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 本机配置系统返回配置错误,因为它对为托管配置节处理程序定义的 类型 属性执行文本比较。 因为 Visual Studio 2008 和 Visual Studio 2008 SP1 生成的所有 Web.config 文件在 system.web.extensions 的类型字符串中都有“3.5”, (和相关) 配置节处理程序, 由于 ASP.NET 4 machine.config 文件在相同配置节处理程序 的 type 属性中具有“4.0”,因此在 Visual Studio 2008 或 Visual Studio 2008 SP1 中生成的应用程序始终无法通过 IIS 7 和 IIS 7.5 中的配置验证。

解决这些问题

第一种方案的解决方法是通过包含 Visual Studio 2008 自动生成的文件中的样本配置文本Web.config来更新应用程序级Web.config文件。

第一种方案的替代解决方法是在计算机上安装 Service Pack 2 for Vista 或 Windows Server 2008,以修复 IIS 配置系统不正确的配置合并行为。 但是,在执行上述任一操作后,应用程序可能会遇到配置错误,因为第二种方案所述的问题。

第二种方案的解决方法是从应用程序级别Web.config文件中删除或注释掉所有 system.web.extensions 配置节定义和配置节组定义。 这些定义通常位于应用程序级 Web.config 文件的顶部,可由 configSections 元素及其子元素标识。

对于这两种情况,建议同时手动删除 system.codedom 节,尽管这不是必需的。

ASP.NET 4 个子应用程序在低于 ASP.NET 2.0 或 ASP.NET 3.5 应用程序时无法启动

由于配置或编译错误,配置为运行 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 配置信息是配置信息层次结构的一部分,该层次结构确定文件夹中子 Web 应用程序 childwebapp 使用的最终合并配置设置。 根据 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。

将父应用程序的 文件中的 configSections 定义 Web.config (运行 ASP.NET 2.0 或 ASP.NET 3.5) 的应用程序移动到 the.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) 上运行,都需要执行此步骤。

Web.config 运行 ASP.NET 2 或 ASP.NET 3.5 的父 Web 应用程序的 文件中,添加一个 位置 标记,该标记显式指定 IIS 和 ASP.NET 配置系统的 (,) 配置条目仅适用于父 Web 应用程序。 以下示例演示要添加 的位置 元素的语法:

<location path="" inheritInChildApplications="false" >
  <!-- Additional settings -->
</location>

以下示例演示如何使用 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 服务器有一个 Web.config 部署在 SharePoint 网站的根目录中的文件 (例如, c:\inetpub\wwwroot\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 版本。 因此,不应尝试在 SharePoint 网站下以子网站的形式运行 ASP.NET 4 网站。

HttpRequest.FilePath 属性不再包含 PathInfo 值

以前版本的 ASP.NET 在从各种文件路径相关属性(包括 HttpRequest.FilePathHttpRequest.AppRelativeCurrentExecutionFilePathHttpRequest.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.PathInfoSomeAction

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 处理。 请按以下过程操作:

  1. 在 Windows 注册表中,打开以下节点:

HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\ASP.NET\4.0.30319.0

  1. 创建名为 EnableExtensionlessUrls 的新 DWORD 值。
  2. EnableExtensionlessUrls 设置为 0。 这会禁用无扩展 URL 行为。
  3. 保存注册表值并关闭注册表编辑器。
  4. 运行 iisreset 命令行工具,使 IIS 读取新的注册表值。

注意

EnableExtensionlessUrls 设置为 1 将启用无扩展 URL 行为。 如果未指定任何值,则这是默认设置。

在 IIS 7 或 IIS 7.5 集成模式下,可能无法在默认文档中引发事件处理程序

ASP.NET 4 包括修改,这些修改更改了当无扩展 URL 解析为默认文档时 HTML 表单元素的操作属性的呈现方式。 解析为默认文档的无扩展 URL 的一个示例是 http://contoso.com/,导致向 http://contoso.com/Default.aspx发出请求。

ASP.NET 4 现在,当向具有映射到默认文档的无扩展 URL 发出请求时,HTML 窗体 元素 的操作 属性值现在呈现为空字符串。 例如,在早期版本的 ASP.NET 中,对 http://contoso.com 的请求将导致对 Default.aspx的请求。 在该文档中,将按以下示例所示呈现开始 窗体 标记:

<form action="Default.aspx" />

在 ASP.NET 4 中,对 http://contoso.com 的请求也会导致对 Default.aspx的请求。 但是,ASP.NET 现在呈现 HTML 打开 窗体 标记,如以下示例所示:

<form action="" />

操作属性呈现方式的这种差异可能会导致 IIS 和 ASP.NET 处理表单 post 的方式发生细微变化。 当 操作 属性为空字符串时,IIS DefaultDocumentModule 对象将创建对 Default.aspx的子请求。 在大多数情况下,此子请求对应用程序代码是透明的,并且 Default.aspx 页面运行正常。

但托管代码和 IIS 7 或 IIS 7.5 集成模式之间可能的交互会导致托管 .aspx 页在子请求期间停止正常工作。 如果出现以下情况,对文档的 Default.aspx 子请求将导致错误或意外行为:

  1. 将 .aspx 页发送到 浏览器,其中表单 元素的 action 属性设置为“”。
  2. 将窗体回发到 ASP.NET。
  3. 托管 HTTP 模块读取实体正文的某些部分。 例如,模块读取 Request.FormRequest.Params。 这会使 POST 请求的实体正文读入托管内存中。 因此,实体正文不再对在 IIS 7 或 IIS 7.5 集成模式中运行的任何本机代码模块可用。
  4. IIS DefaultDocumentModule 对象最终运行并创建对文档的 Default.aspx 子请求。 但由于一段托管代码已读取实体正文,因此没有可发送给子请求的实体正文。
  5. 当 HTTP 管道为子请求运行时,文件的处理程序 .aspx 在处理程序执行阶段运行。
  6. 由于没有实体主体,因此没有窗体变量和视图状态,因此.aspx 页面处理程序没有可用于确定 (事件(如果应引发任何) )的信息。 因此,不会运行针对受影响 .aspx 页的任何回发事件处理程序。

可通过以下方式解决此行为:

  • 确定在默认文档请求期间访问请求实体正文的 HTTP 模块,并确定是否可以将其配置为仅针对托管请求运行。 在 IIS 7 和 IIS 7.5 的集成模式下,HTTP 模块可以通过将以下属性添加到模块的 system.webServer/modules 条目,将 HTTP 模块标记为仅针对托管请求运行:

  • precondition="managedHandler"

  • 此设置将禁用 IIS 7 和 IIS 7.5 确定为非托管请求的请求的模块。 对于默认文档请求,第一个请求是针对无扩展 URL。 因此,在初始请求处理期间,IIS 不会运行任何标记为托管处理程序前提条件的托管模块。 因此,托管模块不会意外读取实体正文,因此实体正文仍然可用,并会一起传递给子请求和默认文档。

  • 如果有问题的 HTTP 模块必须针对静态文件 (的所有请求运行,对于解析为 DefaultDocumentModule 对象的无扩展 URL,对于托管请求等) ,请通过将页面的 System.Web.UI.HtmlControls.HtmlForm 控件的 Action 属性显式设置为非空字符串来修改受影响的 .aspx 页面。 例如,如果默认文档为 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 实现进行了检查。 因此,依赖于全局程序集缓存 (GAC) 中运行的受信任代码的部分信任 ASP.NET 应用程序可能会失败并出现各种安全异常。 依赖于对计算机 CAS 策略进行大量修改的部分信任应用程序也可能失败并出现安全异常。

可以使用信任配置元素中的新 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.HttpUtilitySystem.Web.ClientServices.* 命名空间中的类型以及与成员身份、角色和配置文件相关的类型。 .NET Framework 4 不再支持从非 Web 部分信任应用程序调用这些类型。

注意

System.Web.HttpUtility 类的 HtmlEncodeHtmlDecode 功能已移动到新的 .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 应用程序中使用代码访问安全性

已移动 System.Web.Security 命名空间中的 MembershipUser 和其他类型

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 上运行,即使成员身份类型已移动到其他程序集。 类型转发信息已添加到 ASP.NET 4 版本,该版本 System.Web.dll 会自动将这些类型的运行时引用路由到类型的新位置。

但是,在 ASP.NET 4 项目中使用特定成员身份类型且已从早期版本的 ASP.NET 升级的类库将无法编译。 例如,类库项目可能无法编译并报告如下错误:

  • 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

输出缓存更改以更改 * HTTP 标头

在 ASP.NET 1.0 中,Bug 导致指定 Location="ServerAndClient" 为输出缓存设置的缓存页面在响应中发出 Vary:* HTTP 标头。 这还能起到告知客户端浏览器绝不要本地对页进行缓存的作用。

在 ASP.NET 1.1 中,添加了 System.Web.HttpCachePolicy.SetOmitVaryStar 方法,可以调用该方法来抑制 Vary:* 标头。 之所以选择此方法,是因为更改发出的 HTTP 标头在当时被视为潜在的中断性变更。 但是,开发人员对 ASP.NET 的行为感到困惑,bug 报告表明开发人员不知道现有的 SetOmitVaryStar 行为。

在 ASP.NET 4 中,已决定解决根本问题。 Vary:*不再从指定以下指令的响应发出 HTTP 标头:

<%@OutputCache Location="ServerAndClient" %>

因此,不再需要 SetOmitVaryStar 来取消 Vary:* 标头。

在页面上的 @ OutputCache 指令中指定的Location="ServerAndClient"应用程序中,你现在会看到 Location 属性值的名称所隐含的行为 - 也就是说,页面可以在浏览器中缓存,而无需调用 SetOmitVaryStar 方法。

如果应用程序中的页面必须发出 Vary:*,则调用 AppendHeader 方法,如以下示例所示:

HttpResponse.AppendHeader("Vary","*");

或者,可以将输出缓存 位置 属性的值更改为“Server”。

Passport 的 System.Web.Security 类型已过时

ASP.NET 2.0 中内置的 Passport 支持已过时,并且由于 Passport (现在 LiveID) 发生了更改,因此已过时且不受支持。 因此,与 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 无法呈现图像

在 ASP.NET 4 中,如果路径包含反斜杠 () ,则不会呈现使用 Menu.StaticPopOutImageUrlMenu.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>

若要更正此问题,请将 StaticPopOutImageUrlDynamicPopOutImageUrl 属性中指定的路径值更改为使用 /) (正斜杠。 以下示例演示此更改:

<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 属性已更改。 有关详细信息,请参阅本文档 The MenuItem.PopOutImageUrl 属性未能在 ASP.NET 4 的其他地方呈现图像

免责声明

这是一份初稿,并可能在本文所述软件最终商业发布之前进行大幅更改。

本文档中包含的信息代表 Microsoft Corporation 在发布之日对所讨论问题的当前观点。 由于 Microsoft 必须响应不断变化的市场条件,因此不应将其解释为 Microsoft 作出的承诺,并且 Microsoft 无法保证在发布日期之后提供的任何信息的准确性。

本白皮书仅用于提供信息。 MICROSOFT 对本文档中的信息不做任何明示、暗示或法定的担保。

用户有责任遵守所有适用的版权法/著作权法。 在不限制版权所辖权利的前提下,未经 Microsoft Corporation 的明确书面许可,本文档的任何部分不得被复制、存储或引进检索系统,或者以任何形式、任何方式(电子、机械、影印、录音等)或为任何目的进行传播。

Microsoft 可能拥有本文档所涵盖主题的专利、专利申请、商标、版权或其他知识产权。 除非 Microsoft 提供了明确的书面许可协议,否则提供本文档并不意味着赋予您这些专利、商标、版权或其他知识产权的任何许可。

除非另有说明,否则此处描述的示例公司、组织、产品、域名、电子邮件地址、徽标、人员、地点和事件都是虚构的,不应与任何真实的公司、组织、产品、域名、电子邮件地址、徽标、人员、地点或事件关联,也不应推断。

© 2010 Microsoft Corporation。 保留所有权利。

Microsoft 和 Windows 是 Microsoft Corporation 在美国和/或其他国家/地区的注册商标或商标。

此处提到的真实公司和产品的名称可能是其各自所有者的商标。