29

我有一个 ASP.NET Web 应用程序项目,它通过实体框架连接到远程数据库。在调试期间(例如在我的本地计算机上运行项目),数据库的 IP 地址与发布期间不同(例如在将项目上传到我的网络服务器并从浏览器运行之后)。到目前为止,我一直手动更改 Web.config 文件中的数据库连接字符串以在两者之间切换(基本上我必须连接字符串,一个名为“Debug”,一个名为“Release”,我只是在部署时交换名称)。

现在我刚刚注意到应该可以通过Web.config 转换语法让这种情况自动发生,您将修改后的连接字符串放在 Web.Release.config 版本中,然后当 DLL 在 Release 配置下构建时它应该使用它.

然而它似乎对我不起作用......

这是我的常规 Web.config 文件的相关部分(其中包含本地使用的 Debug 连接字符串):

<?xml version="1.0"?>
<configuration>

  <connectionStrings>
    <!-- Debug connection string. Release connection string is in Web.Release.config file -->
    <add name="DatabaseEntities" connectionString="A" providerName="System.Data.EntityClient" />
  </connectionStrings>

</configuration>

这是 Web.Release.config 文件,根据示例,如果 DLL 处于发布模式,则应将“DatabaseEntities”连接字符串“A”替换为“B”:

<?xml version="1.0"?>
<configuration xmlns:xdt="http://schemas.microsoft.com/XML-Document-Transform">

  <!-- Replace the DatabaseEntities connection string with the Release version (local IP address) -->
  <connectionStrings>
    <add name="DatabaseEntities"
      connectionString="B"
      xdt:Transform="Replace" xdt:Locator="Match(name)"/>
  </connectionStrings>

</configuration>

(显然“A”和“B”只是我真实连接字符串的占位符)

当我调试应用程序(例如,只需按 F5)时,使用默认的 Web.config,我可以访问数据库。然后我通过配置管理器将构建配置更改为发布。解决方案中的所有项目都设置为发布配置。然后我构建解决方案(仅通过构建,甚至通过完整的重建(例如清理、重建))。我将新建的 DLL 以及 Web.config 和 Web.Release.config 文件上传到网络服务器,当我尝试访问我无法访问的数据库时,它仍在尝试通过调试 IP 地址访问数据库因此找不到它...

似乎 Web.Release.config 文件被完全忽略了,或者至少连接字符串没有被替换。

我究竟做错了什么?转换语法是否错误?我没有在发布模式下正确构建应用程序吗?

4

6 回答 6

51

然后我构建解决方案(仅通过构建,甚至通过完整的重建(例如清理、重建))。我将新建的 DLL 以及 Web.config 和 Web.Release.config 文件上传到网络服务器

您的错误是:如果您只是构建,Web 配置转换将不适用于您的本地环境。你需要发布。

您的部署过程看起来很奇怪:您只是在复制 DLL、Web.config 和 web.Release.config。在我看来,您复制的是源代码而不是已编译的应用程序。已发布的 WebApplication 不包含 web.release.config。

您应该将您的项目(右键单击您的 WebApplication -> Publish)发布到本地文件系统并从那里复制文件,或者使用您选择的其他部署方法。

2 年前,我写了一篇关于 web.config 转换的文章。它为您提供了 VS 2010 的分步教程(VS 2012 中更改了发布对话框):http ://www.tomot.de/en-us/article/5/asp.net/how-to-use -web.config-transforms-to-replace-appsettings-and-connectionstrings

于 2013-01-19T16:03:32.937 回答
3

我认为只有在您发布网站/应用程序时才能完成转换。构建应用程序时未完成。后者会在源代码控制下不断更改 web.config(这将是一个真正的麻烦)

于 2014-08-14T06:47:57.177 回答
3

你可以试试 Slow Cheetah 插件:

http://visualstudiogallery.msdn.microsoft.com/69023d00-a4f9-4a34-a6cd-7e854ba318b5

这将通过为您提供额外的上下文菜单选项,让您看到“实时”转换。右键单击并选择 Preview Transform 以查看转换,而无需进行构建。它对于实现 app.config 转换也非常方便

于 2014-06-12T08:27:14.003 回答
1

如果只有在 web.config 转换期间未覆盖的连接字符串,那么这就是我所做的:我清除了“发布 Web”向导的“设置”部分中的“在运行时使用此连接字符串”复选框。此设置正在覆盖连接字符串的 web.config 转换。

于 2015-05-04T19:20:06.873 回答
1

Inside your csproj file, you can add an action to execute before every build and perform the web.config transformations:

<Target Name="BeforeBuild">
    <TransformXml Source="web.config" Transform="web.$(Configuration).config" Destination="web.config" />
</Target>
于 2018-09-21T09:01:09.720 回答
0

它非常灵活,您应该能够进行一些调整以在构建上应用自定义转换(并且无需发布)

我们在我们的(Windows 服务)项目中实现了这一点,在构建上应用了转换

您将需要修改您的项目文件并添加类似于下面的内容

在这里,我们告诉 msbuild 在完成编译后应用转换,但前提是条件为真(请参阅https://docs.microsoft.com/en-us/visualstudio/msbuild/msbuild-conditions?view=vs-2017

请注意,我们正在使用构建道具(自定义 msbuild 道具)“Env”,例如msbuild ... /p:Env=Prod会导致App.Prod.config

<UsingTask TaskName="TransformXml" AssemblyFile="C:\Some\Path\Microsoft.Web.Publishing.Tasks.dll" />
<Target Name="AfterCompile" Condition="Exists('some condition')">
  <!--Generate transformed app config in the intermediate directory-->
  <TransformXml Source="App.config" Destination="$(IntermediateOutputPath)$(TargetFileName).config" Transform="App.$(Env).config" />
  <!--Force build process to use the transformed configuration file from now on.-->
  <ItemGroup>
    <AppConfigWithTargetPath Remove="App.config" />
    <AppConfigWithTargetPath Include="$(IntermediateOutputPath)$(TargetFileName).config">
      <TargetPath>$(TargetFileName).config</TargetPath>
    </AppConfigWithTargetPath>
  </ItemGroup>
</Target>
于 2018-10-24T17:53:38.720 回答