第一次嘗試需要在web.config設定appSettings的共用元件,因此打包NuGet Package時要多加入修改web.config的安裝腳本,其中有些小眉角,我摸索了一陣子才搞定,以下是心得分享。
我要做的事是在appSettings裡新増一筆<add key="afa:WebApiUrl" value="Web API測試台網址" />,在NuGet Package的做法是在content目錄加入web.config.install.xdt及web.config.uninstall.xdt,NuGet便會在安裝及解除安裝時依據這兩個檔案的指示修改web.config。XDT(Microsoft Xml Document Transformation)是微軟發明的XML文件轉換規則,ASP.NET專案透過web.debug.config、web.release.config為偵錯及正式發布產生不同web.config,也是運用相同原理。參考
XDT的基本語法不難,本質上就是個XML,額外加註xdt:Transform="Insert"/xdt:Transform="Replace"之類的指令新増、覆寫或移除XML元素。NuGet官網有如何用XDT修改config的簡單介紹,不過我遇上一個小難題…
在web.debug.config應用情境中,web.config的內容也由我們掌握,是對已知的XML結構進行操作。而NuGet Package被安裝到各式專案時,當時的web.config長什麼樣子是未知的,故轉換邏輯必須很有彈性。例如:若web.config己經有<appSettings>,直接在其中新増一筆<add>即可;若還沒有<appSettings>,就要連<appSettings>一起新増,再插人<add>。
實測時,我就遇到web.config缺少<appSettings>導致安裝失敗的狀況。爬文找到一個xdt:Transform="InsertIfMissing",貌似能見機行事,發現缺少才新増,幾經嘗試不成,才發現很多人反應該篇文章示範的做法有問題,在stackoverlow上找到網友分享的一記妙招:先在XML文件開頭新増一個<appSettings>,將<add>加入文件中「最後一個<appSettings>」,有兩種情況:
- web.config原本就有<appSettings>,XML中有兩個<appSettings>,<add>被加在原本的<appSettings>,第一個<appSettings>是空的
- web.config原本沒有<appSettings>,XML中有一個<appSettings>其中包含剛才加入的<add>
最後,刪除沒有元素的<appSettings>,將第一種狀況產生的重複<appSettings>清除,大功告成,非常聰明。
我試出來的web.config.install.xdt如下,這才成功加入appSetting設定。
<?xmlversion="1.0"encoding="utf-8" ?>
<configurationxmlns:xdt="http://schemas.microsoft.com/XML-Document-Transform">
<appSettingsxdt:Transform="InsertBefore(/configuration/*[1])"/>
<appSettingsxdt:Locator="XPath(/configuration/appSettings[last()])">
<addkey="afa:WebApiUrl"value="測試台Web API URL"xdt:Transform="Insert"/>
</appSettings>
<appSettingsxdt:Transform="RemoveAll"xdt:Locator="Condition(count(*)=0)"/>
</configuration>
解除安裝的web.config.uninstall.xdt相對單純
<?xmlversion="1.0"encoding="utf-8" ?>
<configurationxmlns:xdt="http://schemas.microsoft.com/XML-Document-Transform">
<appSettings>
<addkey="afa:WebApiUrl"xdt:Transform="Remove"xdt:Locator="Condition(count(*)=0)"/>
</appSettings>
</configuration>
補記一個小眉角:反覆測試時,記得每次測試的NuGet Package版號要不同,不然Visual Studio用Cache住的舊版,害你做白工。(我是歷經「怎麼改都不成功,怒拔xdt錯誤居然結果相同」才頓悟 orz)