案情如下,同事在本機開發的ASP.NET Web Site Project,測試妥當要部署到測試台IIS,由於屬現有網站的新增服務,故路徑掛在原有Protal之下(例如: /SomePortal/NewModule/Func.aspx),但自成Web Application,擁有獨立的AppPool。程式搬到測試台後,某行ODP.NET程式立刻爆炸:
OracleCommand cmd = new OracleCommand(sql);

錯誤訊息為: CS0433: The type 'Oracle.DataAccess.Client.OracleCommand' exists in both 'c:\WINDOWS\assembly\GAC\Oracle.DataAccess\9.2.0.700__89b483f429c47342\Oracle.DataAccess.dll' and 'c:\WINDOWS\Microsoft.NET\assembly\GAC_32\Oracle.DataAccess\v4.0_4.112.3.0__89b483f429c47342\oracle.dataaccess.dll'

錯誤訊息明顯指出是ODP.NET 11跟9207版本打架。新專案使用ODAC 11版,而原Portal有舊程式使用ODP.NET 9207,故測試主機ODP.NET 11與9.2版Client並存在預期之內。重點是,很確定新專案裡沒有任何元件引用ODP.NET 9207,全部參考的都是11版,是誰招來9207攪亂一池春水?

靈機一動,查了SomePortal/web.config抓出元凶。在SomePortal的web.config中有以下內容:

<assemblies>
      <add assembly="Oracle.DataAccess, Version=9.2.0.700, Culture=neutral, PublicKeyToken=89B483F429C47342"/>
</assemblies>

NewModule雖是獨立Web Application,AppPool是.NET 4.0,當放被在SomePortal目錄之下,即便其AppPool不同(而且還是.NET 2.0),看來web.config仍會互相影響,做了嘗試,在NewModule web.config用remove設定將9207移除。

<assemblies>
    <remove assembly="Oracle.DataAccess, Version=9.2.0.700, Culture=neutral, PublicKeyToken=89B483F429C47342"/>
    <add assembly="Oracle.DataAccess, Version=4.112.3.0, Culture=neutral, PublicKeyToken=89B483F429C47342" />
</assemblies>

還沒做好心理準備問題就解了 XD。啊~ 福氣啦!

筆記: 但此結果得知,web.config的繼承關係會跨越不同的AppPool,甚至不同版本Runtime。未來在檢測類似問題時,又多了一個追查方向。


Comments

Be the first to post a comment

Post a comment