使用IIS搭配localDb的問題處理
前言
為了提升測試的隔離性,localDb是很好的選擇。但最近遇到一個問題,localDb在進行單元測試的時候都沒有問題,可在整合測試,因為測試目標是掛載在IIS下的API,便會出現無法存取localDb的錯誤,讓人摸不著頭緒,但後來才發現,原來問題就是出在IIS。
為何會如此?
首先來看呼叫Api時所出現的錯誤訊息
看來來是連不到SQL,除此之外看不出有任何異常,為了保險起見,又另外用Sql Management登入測試,登入也正常,確認localDb是存在的,所以問題是IIS連不到。
接下來去windows log的事件檢視器瞧瞧,看能不能有甚麼端睨,從windows log的事件檢視器看到下列事件紀錄說明是存取拒絕,看到這裡大概就是往權限方面去思考。
再往下看會伴隨這個錯誤紀錄,很明顯可以看到幾個關鍵字,一個是user profile,一個是IIS,串起來似乎是說只要能夠載入profile,就能解決這個問題。
該怎麼做?
要允許載入profile,需要設定iis的config,一般來說路徑會在C:\Windows\System32\inetsrv\config
打開該檔案找到applicationPools的區塊
接著看API是掛在哪個pool下,我的案例是我的API掛在DefaultAppPool下,所以我新增設定在該pool下方,然後重啟IIS的pool,設定如下圖所示。
因為sqllocalDb是屬於private性質,所以IIS如果想要存取,必須把sqllocalDb share出來,打開cmd輸入已下指令,即可share 指定的sqllocaldb Instance
完成之後執行sqllocaldb i 確認是否成功建立共享,畫面應該如下圖所示
localDb共享出來之後,接著新增localDb的登入帳號,並設定可存取的資料庫權限。
//新增登入帳號
CREATE LOGIN [IIS APPPOOL\DefaultAppPool] from windows;
//加入admin群組
exec sp_addsrvrolemember N'IIS APPPOOL\DefaultAppPool', sysadmin
如果是用UI操作請參考下圖
最後,SqllocalDb的連接字串設定成"Data Source= (localdb)\.\ErpNextTestShare;Initial Catalog=指定的資料庫名稱;Integrated Security=true;"就可正常運行了。
結論
總結剛剛的操作步驟
- 設定iis config => 為了載入user profile
- 設定localDb share => 為了解除localDb屬於單一使用者並預設私有的限制
- 新增localDb 登入帳號 => 要讓iis可以使用windows驗證的方式登入
因此探討問題的本質,可以發現localDb有下列兩項特性
- localDb需要user的profile才能載入
- localDb實例的擁有者是屬於單一的使用者並且預設是私有的
這樣一切就變得合理了。以上,紀錄完畢。