web-dev-qa-db-ja.com

Web.config Build vs Releaseトランスフォームが機能しない

Entity Frameworkを介してリモートデータベースに接続するASP.NET Webアプリケーションプロジェクトがあります。デバッグ中(たとえば、ローカルコンピューターでプロジェクトを実行)、データベースへのIPアドレスはリリース中とは異なります(たとえば、プロジェクトをWebサーバーにアップロードし、ブラウザーから実行した後)。これまで、Web.configファイルのデータベース接続文字列を常に手動で変更して、2つを切り替えました(基本的には、「Debug」という名前と「Release」という名前の接続文字列が必要で、展開するたびに名前を入れ替えました) )。

今、私はこれを Web.config Transformation Syntax で自動的に実行できるようにする必要があることに気付きました。ここで、変更した接続文字列をWeb.Release.configバージョンに配置し、それを使用する必要がありますDLLはリリース構成の下で構築されます。

しかし、それは私にはうまくいかないようです...

これは、通常のWeb.configファイル(ローカルで使用するためのデバッグ接続文字列を保持)の関連部分です。

<?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ファイルをWebサーバーにアップロードしますが、データベースにアクセスしようとすると、デバッグIPアドレスを介してデータベースにアクセスしようとしています。したがって、それを見つけることができません...

Web.Release.configファイルが完全に無視されているか、少なくとも接続文字列が置き換えられていないようです。

私は何を間違えていますか?変換構文は間違っていますか?リリースモードでアプリケーションを正しくビルドしていませんか?

29
Nick Thissen

次に、ソリューションをビルドします(ビルド経由で、または完全な再構築(例:クリーン、再構築)でも)。新しく構築したDLLをWebサーバーにアップロードするとともに、Web.configファイルとWeb.Release.configファイルをアップロードします

あなたのエラーがあります:単純に構築する場合、Web構成変換はローカル環境では機能しません。公開する必要があります。

展開プロセスは奇妙に思えます。DLL、Web.config、web.Release.configのみをコピーしています。私には、コンパイルされたアプリケーションではなく、ソースコードをコピーしているようです。公開されたWebApplicationにはweb.release.configが含まれていません。

プロジェクトをローカルファイルシステムに公開(WebApplicationを右クリック->公開)し、そこからファイルをコピーするか、選択した別の展開方法を使用する必要があります。

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

51
citronas

変換は、サイト/アプリを公開するときにのみ行われると思いました。アプリケーションの構築時には行われません。後者は、ソース管理下でweb.configを絶えず変更します(これは非常に面倒です)

3
Tom Tavernier

Slow Cheetahプラグインを試すことができます:

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

これにより、追加のコンテキストメニューオプションが提供され、変換が「ライブ」で表示されます。右クリックして[変換のプレビュー]を選択すると、ビルドを行わずに変換を確認できます。また、app.config変換の実装にも非常に便利です

3
KerSplosh

Csprojファイル内で、すべてのビルドの前に実行するアクションを追加し、web.config変換を実行できます。

<Target Name="BeforeBuild">
    <TransformXml Source="web.config" Transform="web.$(Configuration).config" Destination="web.config" />
</Target>
1

Web.config変換中に上書きされないのは接続文字列のみである場合、これが私がしたことです。「Webの公開」ウィザードの「設定」セクションで「実行時にこの接続文字列を使用」チェックボックスをクリアしました。この設定は、接続文字列のweb.config変換を上書きしていました。

1
SKos

かなり柔軟です。ビルド時にカスタムトランスフォームを適用するために(および公開することなく)いくつかの調整を行うことができるはずです。

これを(Windowsサービス)プロジェクトに実装し、ビルド時に変換を適用しました

プロジェクトファイルを変更して、以下のようなものを追加する必要があります。

ここでは、条件がtrueの場合にのみ、コンパイルの終了後に変換を適用するように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>
0
Jason