10

我已经设置了一个新的工作角色,并通过 SlowCheetah 为其设置了几个新的配置转换。当我使用选择的新配置之一构建项目时,我确实看到在 \bin 文件夹下创建了 configs 文件夹,正如您所期望的那样(例如 \bin\Production)。

当我使用其中一个新配置打包云服务以进行部署时,我的 Web 项目的配置得到了适当的转换,但我的工作角色(只是一个库)没有,即使我在 \bin 文件夹下看到更新的 \bin\生产。

看起来天蓝色的打包工具忽略了工作角色库的配置集。我怎样才能让它从适当的配置中选择配置文件?

4

4 回答 4

10

是的,你可以做到这一点——一旦你知道如何做到这一点,它甚至非常容易。
App.config 没有被设计转换,但幸运的是,Azure 团队使构建/部署过程非常适合这些场景。您需要做的事情是相当有据可查的,尽管是以一种非常迂回的方式,并且大多数文章都假设您已经熟悉 MSBuild 脚本等。

您将在下面找到您需要放入项目中的行,这些行将使这个 Just Work。这应该不会超过五分钟。请注意,这不是 hack - 整个 Azure 部署过程旨在支持这种事情。

如果您想了解更多,底部有一些相关文章的链接。

一些概念点

  1. 在 Azure 中实现这种事情的推荐方法是使用 Web.config 和 App.config,而是使用 CloudConfigurationManager 并使用角色设置。但是,有时这并不是正确的答案,通常是因为需要 *.config 设置(smtp、wcf、elmah 等)的内置或第三方组件。
  2. Web Config 转换旨在仅转换 web.config。这意味着 app.config 不是通过设计转换的。
  3. Web Config 转换旨在仅在发布时启动,因此当您在本地运行时,即使在 Cloud Emulator 中,您的 Web.config 也不会被转换。

我们可以解决这个问题的方法是挂钩到 Cloud 项目的构建过程。当您将项目部署到 Azure 时,将使用您可以挂钩的构建过程来构建云项目。简而言之,云项目构建了 web 和 worker 角色,并将它们放在你的云项目下的 Obj 文件夹下。然后,它运行一个基本上压缩所有内容的过程,最后将结果放入 Bin 文件夹。从那里,“zip”文件和配置文件被上传到 Azure。

解决方案

是手动编辑您的 Cloud.csproj 文件(如果您从 Visual Studio 中执行此操作,则需要先卸载项目)。</project>然后将其添加到结束标记的正上方:

  <Import Project="$(MSBuildExtensionsPath)\Microsoft\VisualStudio\v11.0\Web\Microsoft.Web.Publishing.targets" />
    <PropertyGroup>
      <WorkerRoleDir>$(IntermediateOutputPath)WorkerRole1\</WorkerRoleDir>
      <AppConfigOriginal>$(WorkerRoleDir)WorkerRole1.dll.config</AppConfigOriginal>
      <AppConfigTransformer>$(SolutionDir)WorkerRole1\App.$(Configuration).config</AppConfigTransformer>
      <AppConfigAfterTransformed>$(WorkerRoleDir)AfterTransformed.config</AppConfigAfterTransformed>
    </PropertyGroup>
    <Target Name="TransformAppConfig" AfterTargets="AfterPackageComputeService">
      <Message Text="Transforming $(AppConfigOriginal) via $(AppConfigTransformer) to $(AppConfigAfterTransformed)" />
      <TransformXml Source="$(AppConfigOriginal)" Transform="$(AppConfigTransformer)" Destination="$(AppConfigAfterTransformed)" />
      <Copy SourceFiles="$(AppConfigOriginal)" DestinationFiles="$(WorkerRoleDir)App.Config.Original" />
      <Copy SourceFiles="$(AppConfigAfterTransformed)" DestinationFiles="$(AppConfigOriginal)" />
    </Target>

笔记

  • 那里有几个硬编码的路径,您必须对其进行修改。我确信有一种方法可以让它们变软,但这需要比我更多的 MSBuild 技能。
  • 当您部署到本地云模拟器时,转换实际上会运行,但不会被使用。因此,结果与未转换的 Web.config 的行为一致。但是,如果您的转换失败,即使只是在模拟器中运行,您也会收到构建错误。
  • 另请参阅This other SO question
  • 深入探索
  • Tom Hollanders 高度链接文章直接从 MSBuild 部署
于 2013-01-19T11:29:38.343 回答
9

我觉得@Frans 的答案太复杂了,下面是我在互联网上找到的代码。鉴于您已经设置好 app.config 转换并开始工作,请在文本编辑器中打开您的云项目 (.ccproj),找到以下行:

<Import Project="$(CloudExtensionsDir)Microsoft.WindowsAzure.targets" />

并在其后插入以下内容:

  <!-- Get worker role transform start -->
  <Target Name="CopyWorkerRoleConfigurations" AfterTargets="CopyWorkerRoleFiles">
    <Copy SourceFiles="$(WorkerTargetDir)\YOUR-PROJECT-NAME.dll.config" DestinationFolder="$(IntermediateOutputPath)YOUR-PROJECT-NAME" OverwriteReadOnlyFiles="true" />
  </Target>
  <!-- Get worker role transform end -->

并将 YOUR-PROJECT-NAME 替换为您的工作项目名称。

更新

实际上,我找到了一种更好的方法(MSBuild 4+):如果您在 Azure 项目中拥有超过 1 个具有 app.config 转换的辅助角色,则上面的脚本将不起作用。这是更通用的方法:

  <Target Name="CopyWorkerRoleConfigurations" AfterTargets="CopyWorkerRoleFiles">
    <PropertyGroup>
         <RootFolder>$([System.IO.Path]::GetDirectoryName($(MSBuildProjectDirectory)))</RootFolder>
    </PropertyGroup>

    <Copy SourceFiles="$(RootFolder)\%(ProjectName)\bin\$(Configuration)\%(EntryPoint).config" DestinationFolder="%(WorkerRoleReferences.OutputDir)" OverwriteReadOnlyFiles="true" />
  </Target>  
于 2013-05-25T11:21:49.477 回答
0

确保您已设置云服务配置。右键单击云项目,您应该会看到您尝试打包的配置。例如,我重命名并使用本地、测试和生产配置。然后,您的云服务项目应包含 3 个配置文件:

  • 服务配置.Local.cscfg
  • 服务配置.PROD.cscfg
  • 服务配置.TEST.cscfg

右键单击云服务项目并选择“包”并为您的部署选择正确的服务和构建配置。

注意:除非您添加 MS,否则 app.configs 不会在构建过程中进行转换 -请参阅此 SO 答案以了解在构建过程中进行转换的技术。但是,对于云部署,最好将 ServiceConfiguration.*.cscfg 文件与CloudConfigurationManager.GetSetting("settingsKey")- CloudConfigurationManager.GetSetting 结合使用 - SDK 1.7 中添加 - 如果在角色中,它从 ServiceConfig 获取值,否则从 web.config/app.config 获取应用设置

于 2012-12-11T20:56:05.217 回答
0

有一个窍门。也许有人会派上用场。Azure 辅助角色生成器包括标记为“复制”的文件。但是 app.config 将在 WorkerRole1.dll.config (或其他一些)中进行转换,这在设计时不存在。作弊VS:

卸载角色项目 .csproj。

在项目中找到包含文件的 ItemGroup 部分。我有接下来的几个:

<None Include="app.config">
  <SubType>Designer</SubType>
</None>
<None Include="app.Debug.config">
  <DependentUpon>app.config</DependentUpon>
</None>
<None Include="app.Release.config">
  <DependentUpon>app.config</DependentUpon>
  <SubType>Designer</SubType>
</None>

然后在之前或之后设置:

<Content Include="bin\$(Configuration)\WorkerRole1.dll.config">
  <CopyToOutputDirectory>Always</CopyToOutputDirectory>
  <Link>WorkerRole1.dll.config</Link>
</Content>

这个技巧说构建器“WorkerRole1.dll.config”作为链接存在,这个将在构建(和转换)后获得并包含在 WorkerRole 包中。

于 2018-05-30T08:49:04.203 回答