Web.config の内容を発行先やビルド構成で切り替える

SPECIAL


Web.config の内容を ASP.NET and Web Tools の機能を使って切り替える

Microsoft Visual Studio 2012 を使って ASP.NET の Web サイトを作成しているときに、発行先やビルド構成に応じて Web.config の内容を調整したいことがありました。

たとえば、検証用と本番用で別々のデータベースにアクセスしたいときとか、クロスサイト HTTP リクエストに Web.config で対応するときに Debug 構成のときだけ "Access-Control-Allow-Origin" ヘッダーを "*" にしたい場面で、Web.config の内容を切り替えられれば、対応がずっと楽になります。

 

このように状況に応じて Web.config の内容を切り替えることは、Microsoft Azure Web サイトへ簡単に発行できるようにする の中でインストールした Windows Azure SDK for .NET に含まれる "ASP.NET and Web Tools" の機能を使って実現できます。

切り替えると書きましたが、正確には、ベースになる Web.config の内容の一部を「Config 変換」の機能を使って、発行先やビルド構成に応じて置き換えます。

ビルド構成に応じて Web.config の内容を置き換える

ASP.NET and Web Tools がインストールされていると、Web.config が "Debug" 用と "Release" 用の 2 つの設定ファイルが用意されています。

設定内容は Web.config をベースにして、その下の階層にぶら下げられている config ファイルに記載されている内容で、ベースの Web.config の内容を置き換えます。

Debug 構成のときは "Web.Debug.config" に記載されている内容が、Release 構成のときは "Web.Release.config" に記載されている内容が、ベースの Web.config に適用されます。

 

これを使って、たとえば Web.config に記載されている内容のうち、<connectionStrings> の <add name="DB" ...> だけを Release ビルド時に書き換えたいときには、次のような内容を "Web.Release.config" に記載します。

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

<connectionStrings>

<add name="DB" providerName="System.Data.SqlClient" connectionString="Data Source=192.168.1.128; Initial Catalog=ReleaseDB; Persist Security Info=True" xdt:Transform="Replace" xdt:Locator="Match(name)" />

</connectionStrings>

</configuration>

書き方は通常の Web.config と似ていますが、ここで重要になるのが "xdt:Transform" 属性と "xdt:Locator" 属性です。これらの属性を指定することで、これに合致する Web.config の設定内容を書き換えられます。

 

今回の例では <add> タグ内でこれらの属性を指定しています。

"xdt:Transform" 属性で "Replace" を指定することで、Web.config の内容をこの内容に置き換えることを指定しています。このとき <add> タグは複数ある可能性があるので、"xdt:Locator" 属性で "Match(name)" を指定することで、Web.config 内にある <add> タグの name 属性が、ここの <add> タグで指定している name 属性と一致するものを置き換えるように指定しています。

これによって、この例では Web.config の <add name="DB" ...> の内容が、Release ビルドのときだけ "Web.Release.config" に書かれた内容に置き換えられるようになります。

発行先に応じて Web.config の内容を切り替える

プロジェクトに登録してある発行先に応じて Web.config の内容を書き換えたい場合には、PublishProfiles フォルダー内にある目的の発行先 (*.pubxml) で右クリックして「Config 変換を追加」を選択します。

 

このようにすることで、この発行先へプロジェクトを発行するときにだけ適用される Web.config 変換ファイルが生成されます。

ここに、ビルド構成毎の設定の記載のときと同じように "xdt:Transform" 属性や "xdt:Locator" 属性を使って、発行時に適用する設定内容を記載していきます。

たとえば、本運用環境にアップロードしたときにだけ、レスポンスヘッダー "Access-Control-Allow-Origin" の値を "http://ez-net.jp" にしたいときには、次のような内容を、発行先名が付けられた config ファイルに記載します。

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

<system.webServer>

<httpProtocol>

<customHeaders>

<add name="Access-Control-Allow-Origin" value="http://ez-net.jp" xdt:Transform="Replace" xdt:Locator="Match(name)"/>

</customHeaders>

</httpProtocol>

</system.webServer>

</configuration>

このようにすることで、対象のサーバーへ発行したときにだけ、この設定が有効になります。

このときの変換の流れは、基本になる Web.config の内容に対して、ビルド構成に応じた config 変換が適用され、その上で、発行先に応じた config 変換が適用されます。

 

config 変換で指定できる内容

xdt:Transform で指定できる内容

基本になる Web.config をどのように変換するかを指定するのに "xdt:Transform" 属性が使われますが、この属性では次のものを指定できるようになっています。

Replace Web.config の内容を、ここで指定した内容に置き換えます。どの要素を置き換えるかは "xdt:Locator" 属性で指定します。
Insert Web.config の内容に、ここで指定した内容を追加します。タグの最後の要素として挿入されます。"xdt:Locator" 属性による場所の指定は必要ありません。
InsertBefore(XPath) Web.config の内容に、ここで指定した内容を追加します。XPath 形式で指定した要素の前の要素として挿入されます。"xdt:Locator" 属性による場所の指定は必要ありません。
InsertAfter(XPath) Web.config の内容に、ここで指定した内容を追加します。XPath 形式で指定した要素の次の要素として挿入されます。"xdt:Locator" 属性による場所の指定は必要ありません。
Remove Web.config の内容から、ここで指定した内容に該当する要素を削除します。複数の要素が該当する場合は、最初の要素だけが削除されます。"xdt:Locator" を使って削除する要素を指定できます。
RemoveAll Web.config の内容から、ここで指定した内容に該当する要素を削除します。複数の要素が該当する場合は、該当するすべての要素が削除されます。"xdt:Locator" を使って削除する要素を指定できます。
RemoveAttributes(Name, ...) Web.config の内容から、引数で指定した属性を、該当する要素内から削除します。複数の要素が該当する場合は、該当するすべての要素が対象になります。"xdt:Locator" を使って対象の要素を指定できます。
SetAttributes(Name, ...) Web.config の内容にある、引数で指定した属性を、該当する要素内に設定します。設定する属性の値は、その要素内で定義しておきます。複数の要素が該当する場合は、該当するすべての要素が対象になります。"xdt:Locator" を使って対象の要素を指定できます。

xdt:Locator で指定できる内容

基本になる Web.config の内容を "xdt:Transform" 属性で変換するときに、具体的にどの要素を変換対象とするかを指定するのに "xdt:Locator" 属性が使われます。ここでは、次のようなものを使って変換対象の要素を指定することになります。

Match(Name, ...) この xdt:Locator を記載した要素の属性値と Web.config 内の属性値が一致する要素を変換対象とします。どの属性値が一致するかは、Match の引数で指定します。
XPath(XPath) XPath で指定した Web.config 内の要素を変換対象とします。絶対パスで指定します。たとえば name="DB" が設定されている接続文字列を変換したい場合は、"XPath(/configuration/connectionStrings/add[@name='DB'])" のように指定します。
Condition(XPath) XPath で指定した条件に合致する Web.config 内の要素を変換対象とします。この xdt:Locator が記載されている要素自体からの相対パスで指定します。 たとえば name="DB" が設定されている接続文字列を変換したい場合は、"Condition(@name='DB')" のように指定します。

この xdt:Locator は省略することも可能です。

たとえば <system.web> 内の <compilation> タグでは、"debug" 属性に "true" を指定することでデバッグバイナリを生成できますが、本運用のサーバーへ発行するときにはこれを指定せずに、リテールビルドにしたい場合があります。

このとき <compilation> タグは 1 つしか登場しないため、xdt:Locator の指定が必要ありません。

本運用のサーバーへ発行するときに適用する config 変換ファイル内に <compilation xdt:Transform="RemoveAttributes(debug)" /> のように記載するだけで、<compilation> から "debug" 属性を取り除くことが可能です。