使用 Web 部署使 Web 应用程序脱机

作者 :Jason Lee

本主题介绍如何在自动部署期间使用 Internet Information Services (IIS) Web 部署工具 (Web 部署) 使 Web 应用程序脱机。 浏览到 Web 应用程序的用户将重定向到 App_offline.htm 文件,直到部署完成。

本主题是一系列教程的一部分,这些教程基于名为 Fabrikam, Inc 的虚构公司的企业部署要求。本教程系列使用示例解决方案( Contact Manager 解决方案)来表示具有实际复杂程度的 Web 应用程序,包括 ASP.NET MVC 3 应用程序、Windows Communication Foundation (WCF) 服务和数据库项目。

这些教程的核心部署方法基于了解项目文件中所述的拆分 项目文件方法,在该方法中,生成过程由两个项目文件控制:一个项目文件包含适用于每个目标环境的生成说明,另一个包含特定于环境的生成和部署设置。 在生成时,特定于环境的项目文件将合并到与环境无关的项目文件中,以形成一组完整的生成说明。

任务概述

在很多情况下,需要在对相关组件(如数据库或 Web 服务)进行更改时使 Web 应用程序脱机。 通常,在 IIS 和 ASP.NET 中,可以通过将名为 App_offline.htm 的文件放置在 IIS 网站或 Web 应用程序的根文件夹中来实现此目的。 App_offline.htm文件是标准 HTML 文件,通常包含一条简单的消息,告知用户由于维护而暂时无法使用站点。 虽然 App_offline.htm 文件存在于网站的根文件夹中,但 IIS 会自动将任何请求重定向到该文件。 完成更新后,将删除 App_offline.htm 文件,网站将照常恢复处理请求。

使用 Web 部署对目标环境执行自动或单步部署时,可能需要将添加和删除 App_offline.htm 文件合并到部署过程中。 为此,需要完成以下高级任务:

  • 在用于控制部署过程的MICROSOFT 生成引擎 (MSBuild) 项目文件中,创建一个 MSBuild 目标,用于在任何部署任务开始之前将App_offline.htm文件复制到目标服务器。
  • 添加另一个 MSBuild 目标,用于在所有部署任务完成时从目标服务器中删除 App_offline.htm 文件。
  • 在 Web 应用程序项目中,创建一个 .wpp.targets 文件,该文件确保在调用 Web 部署时将 App_offline.htm 文件添加到部署包中。

本主题将演示如何执行这些过程。 本主题中的任务和演练假定你已创建一个解决方案,该解决方案至少包含一个 Web 应用程序项目,并且使用自定义项目文件来控制部署过程,如 企业中的 Web 部署中所述。 或者,可以使用 Contact Manager 示例解决方案来遵循主题中的示例。

将App_Offline文件添加到 Web 应用程序项目

需要完成的第一个任务是将 App_offline 文件添加到 Web 应用程序项目:

  • 若要防止文件干扰开发过程, (不希望应用程序在) 永久脱机,应调用除 App_offline.htm以外的其他名称。 例如,可以将文件命名 为App_offline-template.htm
  • 若要防止文件按原样部署,应将生成操作设置为 “无”。

将App_offline文件添加到 Web 应用程序项目

  1. 在 Visual Studio 2010 中打开解决方案。

  2. 解决方案资源管理器窗口中,右键单击 Web 应用程序项目,指向“添加”,然后单击“新建项”。

  3. “添加新项 ”对话框中,选择“ HTML 页”。

  4. 在“ 名称 ”框中,键入 “App_offline-template.htm”,然后单击“ 添加”。

    在“名称”框中,键入“App_offline-template.htm”,然后单击“添加”。

  5. 添加一些简单的 HTML 以通知用户应用程序不可用,然后保存该文件。 请勿包含任何服务器端标记 (例如,任何前缀为“asp:”的标记) 。

    添加一些简单的 H T M L 以通知用户应用程序不可用,然后保存文件。

  6. 解决方案资源管理器窗口中,右键单击新文件,然后单击“属性”。

  7. “属性” 窗口的“ 生成操作” 行中,选择“ ”。

    在属性窗口的“生成操作”行中,选择“无”。

部署和删除App_Offline文件

下一步是修改部署逻辑,以在部署过程开始时将文件复制到目标服务器,并在最后将其删除。

注意

下一过程假定使用自定义 MSBuild 项目文件来控制部署过程,如 了解项目文件中所述。 如果要从 Visual Studio 直接部署,则需要使用不同的方法。 Sayed Ibrahim Hashimi 在 如何在发布期间使 Web 应用脱机中介绍了一种方法。

若要将 App_offline 文件部署到目标 IIS 网站,需要使用 Web Deploy contentPath 提供程序调用MSDeploy.exe。 contentPath 提供程序支持物理目录路径和 IIS 网站或应用程序路径,这使得它成为在 Visual Studio 项目文件夹和 IIS Web 应用程序之间同步文件的理想选择。 若要部署文件,MSDeploy 命令应如下所示:

msdeploy.exe –verb:sync
             -source:contentPath="[Project folder]\App_offline.template.htm"
             -dest:contentPath="[IIS application path]/App_offline.htm",
              computerName="[Destination web server]"

若要在部署过程结束时从目标站点中删除文件,MSDeploy 命令应如下所示:

msdeploy.exe –verb:delete
             -dest:contentPath="[IIS application path]/App_offline.htm",
              computerName="[Destination web server]"

若要在生成和部署过程中自动执行这些命令,需要将它们集成到自定义 MSBuild 项目文件中。 下一过程介绍如何执行此操作。

部署和删除App_offline文件

  1. 在 Visual Studio 2010 中,打开用于控制部署过程的 MSBuild 项目文件。 在 Contact Manager 示例解决方案中,这是 Publish.proj 文件。

  2. 在根 Project 元素中,创建新的 PropertyGroup 元素来存储 App_offline 部署的变量:

    <PropertyGroup>
      <AppOfflineTemplateFilename   
        Condition=" '$(AppOfflineTemplateFilename)'=='' ">
          app_offline-template.htm
      </AppOfflineTemplateFilename>
      <AppOfflineSourcePath 
        Condition=" '$(AppOfflineSourcePath)'==''">
          $(SourceRoot)ContactManager.Mvc\$(AppOfflineTemplateFilename)
      </AppOfflineSourcePath>
    </PropertyGroup>
    
  3. SourceRoot 属性在 Publish.proj 文件中的其他位置定义。 它指示源内容的根文件夹相对于当前路径的位置,换言之,相对于 Publish.proj 文件的位置。

  4. contentPath 提供程序不接受相对文件路径,因此需要先获取源文件的绝对路径,然后才能部署它。 可以使用 ConvertToAbsolutePath 任务来执行此操作。

  5. 添加名为 GetAppOfflineAbsolutePath 的新 Target 元素。 在此目标中,使用 ConvertToAbsolutePath 任务获取项目文件夹中 App_offline模板 文件的绝对路径。

    <Target Name="GetAppOfflineAbsolutePath" BeforeTargets="DeployAppOffline">
      <ConvertToAbsolutePath Paths="$(AppOfflineSourcePath)">
        <Output TaskParameter="AbsolutePaths"       
                PropertyName="AppOfflineAbsoluteSourcePath" />
      </ConvertToAbsolutePath>
    </Target>
    
  6. 此目标采用项目文件夹中 App_offline模板 文件的相对路径,并将其作为绝对文件路径保存到新属性。 BeforeTargets 属性指定你希望此目标在 DeployAppOffline 目标之前执行,你将在下一步中创建该目标。

  7. 添加名为 DeployAppOffline 的新目标。 在此目标中,调用 MSDeploy.exe 命令,该命令将 App_offline 文件部署到目标 Web 服务器。

    <Target Name="DeployAppOffline" 
            Condition=" '$(EnableAppOffline'!='false' ">
      <PropertyGroup> 
        <_Cmd>"$(MSDeployPath)\msdeploy.exe" -verb:sync 
               -source:contentPath="$(AppOfflineAbsoluteSourcePath)" 
               -dest:contentPath="$(ContactManagerIisPath)/App_offline.htm",
                computerName="$(MSDeployComputerName)"
        </_Cmd>
      </PropertyGroup>
      <Exec Command="$(_Cmd)"/> 
    </Target>
    
  8. 在此示例中, ContactManagerIisPath 属性在项目文件中的其他位置定义。 这只是一个 IIS 应用程序路径,格式为 [IIS 网站名称]/[应用程序名称]。 在目标中包含条件使用户能够通过更改属性值或提供命令行参数来打开或关闭 App_offline 部署。

  9. 添加名为 DeleteAppOffline 的新目标。 在此目标中,调用从目标 Web 服务器中删除 App_offline 文件的 MSDeploy.exe 命令。

    <Target Name="DeleteAppOffline" 
            Condition=" '$(EnableAppOffline'!='false' ">
      <PropertyGroup> 
        <_Cmd>"$(MSDeployPath)\msdeploy.exe" -verb:delete 
               -dest:contentPath="$(ContactManagerIisPath)/App_offline.htm",
                computerName="$(MSDeployComputerName)"
        </_Cmd>
      </PropertyGroup>
      <Exec Command="$(_Cmd)"/> 
    </Target>
    
  10. 最后一项任务是在项目文件执行期间在适当点调用这些新目标。 可以通过各种方式执行此操作。 例如,在 Publish.proj 文件中, FullPublishDependsOn 属性指定在调用 FullPublish 默认目标时必须按顺序执行的目标列表。

  11. 修改 MSBuild 项目文件,以在发布过程中的适当点调用 DeployAppOfflineDeleteAppOffline 目标。

    <PropertyGroup>
      <FullPublishDependsOn>
        Clean;
        BuildProjects; 
        DeployAppOffline;
        GatherPackagesForPublishing;
        PublishDbPackages;
        DeployTestDBPermissions;
        PublishWebPackages;
        DeleteAppOffline;
      </FullPublishDependsOn> 
    </PropertyGroup>
    <Target Name="FullPublish" DependsOnTargets="$(FullPublishDependsOn)" />
    

运行自定义 MSBuild 项目文件时, App_offline 文件将在成功生成后立即部署到服务器。 然后,完成所有部署任务后,将从服务器中删除它。

将App_Offline文件添加到部署包

根据配置部署的方式,在将 Web 包部署到目标时,目标 IIS Web 应用程序中的任何现有内容(如 App_offline.htm 文件)都可能会自动删除。 为了确保 App_offline.htm 文件在部署期间保持不变,除了在部署过程开始时直接部署文件外,还需要在 Web 部署包本身中包含该文件。

  • 如果已按照本主题中的前面的任务进行操作,则会将 App_offline.htm 文件添加到 Web 应用程序项目中, (我们使用 App_offline-template.htm) ,并将生成操作设置为 “无”。 这些更改是必要的,以防止文件干扰开发和调试。 因此,需要自定义打包过程,以确保 web 部署包中包含 App_offline.htm 文件。

Web 发布管道 (WPP) 使用名为 FilesForPackagingFromProject 的项列表来生成应包含在 Web 部署包中的文件列表。 可以通过将自己的项添加到此列表来自定义 Web 包的内容。 为此,需要完成以下高级步骤:

  1. 在项目文件所在的文件夹中创建一个名为 [project name].wpp.targets 的 自定义项目文件。

    注意

    .wpp.targets 文件需要位于与 Web 应用程序项目文件(例如 ContactManager.Mvc.csproj)相同的文件夹中,而不是与用于控制生成和部署过程的任何自定义项目文件位于同一文件夹中。

  2. .wpp.targets 文件中,创建一个新的 MSBuild 目标,该目标在 CopyAllFilesToSingleFolderForPackage 目标之前执行。 这是 WPP 目标,用于生成要包含在包中的内容的列表。

  3. 在新目标中,创建一个 ItemGroup 元素。

  4. ItemGroup 元素中,添加 FilesForPackagingFromProject 项并指定 App_offline.htm 文件。

.wpp.targets 文件应如下所示:

<Project ToolsVersion="4.0" 
         xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
  <Target Name="AddAppOfflineToPackage"
          BeforeTargets="CopyAllFilesToSingleFolderForPackage">
    <ItemGroup>   
      <FilesForPackagingFromProject Include="App_offline-template.htm">
        <DestinationRelativePath>App_offline.htm</DestinationRelativePath>
    </FilesForPackagingFromProject>
  </ItemGroup>
  </Target>
</Project>

下面是此示例中需要注意的要点:

  • BeforeTargets 属性通过指定应在 CopyAllFilesToSingleFolderForPackage 目标之前立即执行此目标,将它插入 WPP 中。
  • FilesForPackagingFromProject 项使用 DestinationRelativePath 元数据值将文件从 App_offline-template.htm 重命名为App_offline.htm添加到列表中。

下一过程演示如何将此 .wpp.targets 文件添加到 Web 应用程序项目。

将 .wpp.targets 文件添加到 Web 部署包

  1. 在 Visual Studio 2010 中打开解决方案。

  2. 解决方案资源管理器窗口中,右键单击 Web 应用程序项目节点 (例如 ContactManager.Mvc) ,指向“添加”,然后单击“新建项”。

  3. 在“ 添加新项 ”对话框中,选择 “XML 文件” 模板。

  4. 在“ 名称 ”框中,键入 [项目名称].wpp.targets (例如 ContactManager.Mvc.wpp.targets) ,然后单击“ 添加”。

    在“名称”框中,键入项目名称 .wpp.targets,然后单击“添加”。

    注意

    如果将新项添加到项目的根节点,则会在项目文件的同一文件夹中创建该文件。 可以通过在 Windows 资源管理器中打开 文件夹来验证这一点。

  5. 在 文件中,添加前面所述的 MSBuild 标记。

    <Project ToolsVersion="4.0" 
             xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
      <Target Name="AddAppOfflineToPackage"
              BeforeTargets="CopyAllFilesToSingleFolderForPackage">
        <ItemGroup>   
          <FilesForPackagingFromProject Include="App_offline-template.htm">
            <DestinationRelativePath>App_offline.htm</DestinationRelativePath>
        </FilesForPackagingFromProject>
      </ItemGroup>
      </Target>
    </Project>
    
  6. 保存并关闭 [项目名称].wpp.targets 文件。

下次生成和打包 Web 应用程序项目时,WPP 将自动检测 .wpp.targets 文件。 App_offline-template.htm 文件将作为 App_offline.htm包含在生成的 Web 部署包中。

注意

如果部署失败, App_offline.htm 文件将保留到位,应用程序将保持脱机状态。 通常此行为是必需的。 若要使应用程序重新联机,可以从 Web 服务器中删除 App_offline.htm 文件。 或者,如果更正了任何错误并运行成功的部署,则会删除 App_offline.htm 文件。

结论

本主题介绍如何在部署过程中脱机 Web 应用程序,方法是在部署过程开始时将 App_offline.htm 文件发布到目标服务器,并在最后将其删除。 它还介绍了如何在 Web 部署包中包含 App_offline.htm 文件。

深入阅读

有关打包和部署过程的详细信息,请参阅 生成和打包 Web 应用程序项目为 Web 包部署配置参数部署 Web 包

如果直接从 Visual Studio 发布 Web 应用程序,而不是使用这些教程中所述的自定义 MSBuild 项目文件方法,则需要在发布过程中使用略有不同的方法来使应用程序脱机。