[VS2010] ASP.NET 4.0 新功能:Web.config Minification 與 Transformation

[VS2010] ASP.NET 4.0 新功能:Web.config Minification 與 Transformation

image_8

Web.config 最小化(Web.config Minification)

 

相信經常使用 ASP.NET 開發 Web 應用程式的人而言,Web.config 是再熟悉不過的東西了,Web.config 中存放了很多的應用程式設定值,不過通常會動到 Web.config 的機率基本上是不高的,最常變動的不外乎是 ConnectionString 以及 appSettings 這兩區而且,再進階一點就是動 HttpHandler 以及 HttpModule 兩個區塊,其他部份除非自己有設計 Configuration Sections,否則一般都不會去動它,但如果部署出去,很難保客戶哪天不小心動到 Web.config 的內容導致應用程式出問題。

 

如果有看過 Web.config 和 .NET Framework 本身的 maching.config 的人就知道,在 Web.config 中有超過 50% 以上的設定,在 machine.config 中都找的到,那為什麼不將它移動到 machine.config 中呢?筆者試想應該是設定檔有隔離的處理,讓應用程式間的設定不會相互干擾。

 

不過在 ASP.NET 4.0 開始,微軟終於將那些多餘的資料移到 machine.config 了,這麼一來,Web.config 就只有這樣:

 

<?xml version="1.0"?>

<configuration>

<system.web>

<compilation targetFramework="4.0" />

</system.web>

</configuration>

 

是不是乾淨多了呢?而且這樣也不會有被亂改到的問題。

 

Web.config 轉換(Transformation)

 

我想長久以來,Web 應用程式開發人員在處理部署的問題上花的心力也很多,先不說實際部署到用戶端的問題,光是一個在公司內分割不同的環境來測試與開發,就有不少的麻煩,因為 Web.config 檔案只有一個,如果要切分不同的資料庫或是組態設定的話,開發人員總是要在不同的 Web.config 檔案間週旋(複製/修改/更名),讓開發人員煩不勝煩。這在稍微具規模或具嚴謹的開發流程的組織來說卻是很重要且不能避免的,因此微軟勢必要在這個部份想點辦法。

 

XML Document Transformation 是 ASP.NET 4.0 所提出的新功能,它是用來解決不同環境下的 Web 應用程式環境的組態問題,它是一種可以在建置期間 (build-time) 動態將 Web.config 中的內容以不同組態的 Web.config 設定進行替代或轉換的一種機制,這可以讓開發人員依照不同的環境給予不同的 Web.config 組態設定,並且在主要的 Web.config 加入 XML Document Transformation 指令,MSBuild 工具會在建立 Web 應用程式封裝時將指定環境的 Web.config 的內容自動套用到主要的 Web.config 中,開發人員就無需再特別去管理或修改原有的 Web.config。

 

例如,公司在應用程式的開發流程中,分為 development, staging (移轉環境) 與 production 三個環境,每個環境都有不同的資料庫連線字串,以往的 Web.config 的 ConnectionString 設定,如不想在程式中特別設定的話,就需要分成好幾個 Web.config 放,在不同的主機(或不同的站台/虛擬目錄)各放一個 Web.config,很容易造成組態管理 (Configuration Management) 上的困擾:

 

<!--Web.config in development server-->

<?xml version="1.0"?>

<configuration>

<system.web>

<connectionStrings>
  <add name="DevelopmentDB"
       connectionString="data source=developerServer;Integrated Security=SSPI;Initial Catalog=DevelopmentDB"
       providerName="System.Data.SqlClient" />
</connectionStrings>

</system.web>

</configuration>

 

<!--Web.config in staging server-->

<?xml version="1.0"?>

<configuration>

<system.web>

<connectionStrings>
  <add name="DevelopmentDB"
       connectionString="data source=stagingServer;Integrated Security=SSPI;Initial Catalog=stagingDB"
       providerName="System.Data.SqlClient" />
</connectionStrings>

</system.web>

</configuration>

 

<!--Web.config in production server-->

<?xml version="1.0"?>

<configuration>

<system.web>

<connectionStrings>
  <add name="DevelopmentDB"
       connectionString="data source=productionServer;Integrated Security=SSPI;Initial Catalog=productionDB"
       providerName="System.Data.SqlClient" />
</connectionStrings>

</system.web>

</configuration>

 

 

到了 ASP.NET 4.0 時,這個問題可以利用 XML Document Transformation 解決掉,只要保留一種 Web.config 的主要宣告:

 

<!--Web.config-->

<?xml version="1.0"?>

<configuration>

<system.web>

<connectionStrings>
  <add name="DevelopmentDB"
       connectionString="data source=developerServer;Integrated Security=SSPI;Initial Catalog=DevelopmentDB"
       providerName="System.Data.SqlClient" />
</connectionStrings>

</system.web>

</configuration>

 

然後在專案中為特定組態所定義的 Web.config (例如除錯用的命名為 Web.debug.config,正式環境用的是 Web.release.config 等等) 中設定使用 XML Document Transformation 的宣告:

 

<!--Web.debug.config-->

<?xml version="1.0"?>

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

<system.web>

<connectionStrings>
  <add name="DevelopmentDB"
       connectionString="data source=developmentServer;Integrated Security=SSPI;Initial Catalog=developmentDB"
       xdt:Transform="SetAttributes" xdt:Locator="Match(name)"/>

</connectionStrings>

</system.web>

</configuration>

 

<!--Web.relase.config-->

<?xml version="1.0"?>

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

<system.web>

<connectionStrings>
  <add name="DevelopmentDB"
       connectionString="data source=productionServer;Integrated Security=SSPI;Initial Catalog=productionDB"
       xdt:Transform="SetAttributes" xdt:Locator="Match(name)"/>

</connectionStrings>

</system.web>

</configuration>

 

然後使用 Create Package 建立專案的部署檔,MSBuild 就會自動執行 transformation 的動作,將指定組態的 Web.config 內容替換到主要的 Web.config 檔案中(例如 Web.release.config –> Web.config)。

 

image

 

VS_Webconfig_Transformation

 

不過這個功能只有在 Web 應用程式專案(Web Application Project)中才可以使用,目前 Web Site 型專案是無法支援的。

 

XML Document Transformation 說明

 

XML Document Transformation 是一種 XML 文件間的轉換機能,由 MSBuild 工具支援,它可以將指定的 XML 文件中的內容所設定的條件式 (locator) 以及代換動詞 (transform),將來源檔案的元素自動更新到主檔案,例如將 Web.release.config 中的內容代換到 Web.config 中。要支援 XML Document Transformation,則來源檔案必須要引用 http://schemas.microsoft.com/XML-Document-Transform 命名空間,並將前置字元用 xdt 來設定,如:

 

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

 

接著,要在需處理轉換的元素中,加入代換的條件式,以及執行代換時的動作設定,例如:

 

<!--Web.relase.config-->

<?xml version="1.0"?>

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

<system.web>

<connectionStrings>
  <add name="DevelopmentDB"
       connectionString="data source=productionServer;Integrated Security=SSPI;Initial Catalog=productionDB"
       xdt:Transform="SetAttributes" xdt:Locator="Match(name)"/>

</connectionStrings>

</system.web>

</configuration>

 

下列是 XML Document Transformation 的 Locator 條件式所支援的轉換方式:

條件式範例說明
MatchimageMatch模式會偵測在主檔中相同位置內符合相同屬性的值,如果找到的話就會依 Transform 指定的代換方式來修改主檔
ConditionimageCondition模式會檢查在主檔中相同位置內符合由 Condition 設定的條件是否為 true,若是的話依 Transform 指定的代換方式來修改主檔。
XPathimageXPath模式會以設定的XPath路徑運算子來偵測哪些元素符合條件,並依 Transform 指定的代換方式來置換主檔資料。

 

下列是 XML Document Transformation 的 Transform 代換動詞:

 

轉換方式範例說明
Replaceimage Replace 指令會代換符合的元素以及其子元素。
Removeimage Remove 會將第一個符合的元素及其子元素移除。
RemoveAllimage RemoveAll 會將所有符合的元素及其子元素移除。
Insertimage Insert會插入元素到符合的元素之後。
SetAttributesimage SetAttributes會將符合的元素的指定屬性設定為特定值,若有多個屬性要代換的話要用逗號來分隔。
RemoveAttributesimage RemoveAttributes會將符合的元素的指定屬性刪除,若有多的屬性要刪除的話要用逗號來分隔。
InsertAfter(XPath)image InsertAfter會將符合的元素插入到由 XPath 指定的位置之後。
InsertBefore(XPath)image InsertBefore會將符合的元素插入到由 XPath 指定的位置之前。
XSLTimage XSLT會將符合的元素使用指定的XSLT檔案轉換。