2014年8月7日 星期四

讓 Debugging 的時候也可以隨著組態轉換 Web.Config

這一篇的題目跟前一篇「發佈網站時依據組態設定的不同而轉換 Web.Config」相當相似,不過要達成的結果卻是不一樣的,前一篇所講的是在發佈網站時,可以事先透過增加組態設定然後新增相對應的 Web.Config 檔案,然後在發佈網站就可以選擇不同組態而轉換 Web.Config 的內容。

原本要寫的是各位看到的這一篇,但是之前並沒有文章交代有關發佈網站並選組態轉換 Web.Config 的主題,必須要先有前一篇的基礎之後才能夠完成這一篇,不然兩篇的內容寫在一塊,我想現在也很少人會花時間去看一篇冗長的文章了。

這一篇要講的就是我們在 Visua Studio 開發網站時,我們也有增加組態並且編輯相對應 Web.Config 的轉換設定內容,但是當進入偵錯模式的時候卻無法隨著組態選擇的不同而讓偵錯模式下的網站也能有所轉換,因為預設的組態轉換 Web.Config 是只有在發佈網站的時候才有作用,這一篇就是要來說明如何讓我們在偵錯模式下也可以隨著選擇不同的組態而轉換當下的 Web.Config。

 


以下的操作說明主要是參考「Enabling Web Transforms when debugging ASP.NET apps | Vidar's Musings」這篇文章內容,原文是在 Visual Studio 2010 並且是 ASP.NET WebForm 專案下來做說明,而我這篇則是會以 Visual Studio 2013 以及 ASP.NET MVC 的情境下來說明,所以不論是哪一種開發工具以及哪一種專案,都是可以循著相同模式來做更改。

延續前一篇「發佈網站時依據組態設定的不同而轉換 Web.Config」的內容,一樣是使用「ASPNET MVC WebForm Repository Sample」的範例專案,在前一篇已經完成了增加組態以及修改相對應 Web.Config 的置換設定內容,

image

將開發專案的組態選擇為其中一個我們自己所加入的組態,然後進入偵錯狀態,

image

因為我有在網站程式裡去取得目前所使用的 RepositoryType 資料,

image

然後在 _Layout.cshtml 有指定要顯示 RepositoryType 的資訊,

image

所以預期會再進入偵錯模式時所顯示的網頁應該會顯示「Sample.Repository.EF」,但是頁面上所顯示的還是預設所使用的「Sample.Repository.ADONET」,

image

其實會這有這樣的結果是理所當然的,而且是相當正常,前面就有說過,因為增加組態而新增的 Web.Config,其轉換的功能是在發佈網站時才會有作用,所以在開發階段的偵錯模式下,當然就不會有任何作用的。

但假如我們想要在開發階段也希望能夠測試不同組態的設定時,難道還要回頭使用那種手動去做註解與置換的操作處理嗎?

image

 

既然已經新增的組態設定,並且也有增加了組態相對應的 Web.Config,然後也編輯了要置換的設定內容,所以我也相當希望能夠在開發階段的時候,也能夠隨著選擇組態的不同,在進入偵錯模式的時候也可以置換 Web.Config 內容,然後在執行的網站就是使用這些置換後的 Web.Config。

於是我就四處尋找任何可行的解決方案,在開始找之前我就沒有預期能夠找到什麼簡單的解決方案,因為要達到這樣的功能,勢必需要動一些手腳才能夠完成,而這樣的修改都會去更動到 csproj 專案設定檔的內容,有找到很多的文章都有提到如何去修改,只是有些文章只有簡短的文字說明或是沒有詳細的操作步驟,所以對我這樣的庸才來說還是不夠的,於是最後才找到「Enabling Web Transforms when debugging ASP.NET apps | Vidar's Musings」這一篇文章,並且跟著做,也達到預期的成效,而且還不算太複雜,接著就以我的方式來說明整個操作步驟。

 

Step.1

第一步就是先把方案裡的 ASP.NET MVC 網站專案給卸載,

image

image

 

Step.2

接著開啟檔案總管然後到 Sample.Web.MVC 的目錄下,複製 Web.Config 然後新檔案的名稱為「Web.template.Config」,

image

 

Step.3

接著要修改 Sample.Web.MVC.csproj 的內容,這邊我是使用 Sublime Text 3 開啟檔案並且編輯,

image

然後在 Sample.Web.MVC.csproj 檔案裡尋找「Content Include="Web.config"」的內容

image

另外組態相對應的 Web.Config 也需要找出來「Web.EF.Config」「Web.EntLibDAAB.Config」( ItemGroup 範圍 )

image

先把「Web.EF.Config」「Web.EntLibDAAB.Config」的部分給移到上面跟 Web.Config 位置下,

image

再來修改為以下的內容,簡單說就是使用剛才另外複製 Web.Config 然後另外建立的 Web.template.Config,

image

 

Step.4

再來在 Sample.Web.MVC.csproj 的最後加上以下的內容,

<PropertyGroup>
  <BuildDependsOn>
    CustomWebConfigTransform;
    $(BuildDependsOn);
  </BuildDependsOn>
</PropertyGroup>
<Target Name="CustomWebConfigTransform">
  <TransformXml source="Web.template.config" transform="Web.$(Configuration).config" destination="Web.config" />
</Target>

image

上面這一段所加入的內容,也是在做轉換的處理,當我們建置專案的時候,就會依照所選擇組態的不同,然後將來源檔案「Web.template.Config」使用「Web.$(Configuration).config」的內容作轉換,最後把轉換的內容給存為 Web.Config。

 

Step.5

將原本的 Web.Config 重新命名為 「_Web.Config」,因為將過上面的修改之後,每次專案再重新建置之後都會產生新的 Web.Config,而原本的 Web.Config 雖然用不到了,但也不能就此把檔案給刪除,所以就另外改個檔名並予以保留。

image

 

Step.6

完成上面對 Sample.Web.MVC.csproj 的修改之後,回到 Visual Staudio 裡,重新加入 Sample.Web.MVC 專案,

image

重新載入專案之後會看到 Web.Config 檔案有個警告標示,這是正常的,因為我們已經在上一個步驟把 Web.Config 重新命名為「_Web.Config」

image

重新建置專案之後就會建立新的 Web.Config 檔案

image

這時候我們在 Visual Studio 裡選擇其他的組態,

image

然後重新建置專案,再觀察重新產生的 Web.Config 內容,可以看到 Web.Config 裡所指定要置換的地方已經做了轉換,

image

執行網站

使用 Sample.Repository.EntLinbDAAB

image

使用 Sample.Repository.EF

image

使用 Sample.Repository.ADONET(Default)

image

 

要特別注意的地方

因為 Web. Config 檔案是每次建置專案之後會重新產生,所以當我們有使用 NuGet 安裝套件時,有些套件安裝會在 Web.Config 裡做修改與添加內容的處理,所以在重新建置專案之後,原本透過 NuGet 安裝套件對 Web.Config 所做的修改就會不見。

所以當有使用 NuGet 安裝套件後,請務必使用比對工具去比較 Web.Config 與 Web.template.Config 的內容,將 Web.Config 裡有添加或修改的內容給同步到 Web.template.Config 裡,以確保下一次重新建置專案後的 Web.Config 內容沒有遺漏。

例如,我要在 Sample.Web.MVC 專案裡透過 NuGet 加入 Elmah 套件,安裝 Elmah 之後會在 Web.Config 李加入很多新的設定,

image

image

接著就是使用比對工具去比較「Web.Config」與「Web.template.Config」兩個檔案,我所使用的比對工具是「Code Compare」(有免費版的可供使用)

image

可以在 Visual Studio 裡選擇並執行「Compare Selected」

image

或是在檔案總管裡選擇兩個檔案然後使用 Code Compare 來做比對,

image

在 Visual Studio 裡進行逐一比對並且將添加到 Web.Config 的內容給同步到 Web.template.Config 裡,

image

當選擇某一段內容進行同步後,會出現下面的詢問視窗,請務必點選「否」或是「全部皆否」,這一個操作相當重要,請千萬要注意,

image

當全部的內容都比對並同步完成之後,我們就已經把添加在 Web.Config 的內容給同步到 Web.template.Config 了,這麼一來就不用擔心重新建置專案後的 Web.Config 是舊的內容,

image

 


一般來說這樣的操作處理會比較不常見,但是在開發上要做一些設定值的切換還是有需要的,尤其是有多個部署環境的時候,為了要做測試然後觀察結果,並不會延後到使用發行網站才去看結果,通常都是在開發階段裡的偵錯模式就想要知道結果,而同樣的情況下,已經有建立不同組態的 Web.Config 檔案,那麼就透過上述的修改方式讓我們在開發的偵錯狀態下也可以隨著組態選擇的不同而轉換不同的 Web.Config 內容,這樣的轉換操作絕對是比手動去做轉換要來得輕鬆且聰明。

不過這是進階的操作,不適合初學者與一般開發者,如果你的開發團隊想要用這個方法的話,請交給資深的開發成員來做,不然會讓團對搞得灰頭土臉的,而且團隊必須要先知道「發佈網站時依據組態設定的不同而轉換 Web.Config」並且有使用。

詳細的轉換說明與描述,就請大家詳閱參考連結裡的文章。

 

參考連結

Enabling Web Transforms when debugging ASP.NET apps | Vidar's Musings

 

以上

沒有留言:

張貼留言

提醒

千萬不要使用 Google Talk (Hangouts) 或 Facebook 及時通訊與我聯繫、提問,因為會掉訊息甚至我是過了好幾天之後才發現到你曾經傳給我訊息過,請多多使用「詢問與建議」(在左邊,就在左邊),另外比較深入的問題討論,或是有牽涉到你實作程式碼的內容,不適合在留言板裡留言討論,請務必使用「詢問與建議」功能(可以夾帶檔案),謝謝。