2013-03-14 66 views
3

我有用C#4.0編寫的ASP.NET Web應用程序。應用程序引用自帶配置文件的類庫。在運行時,類庫使用類似於下面的代碼加載這個具體配置:IIS Web應用程序和類庫配置 - 配置文件部署時丟失

var exeConfigPath = this.GetType().Assembly.Location; 
var config = ConfigurationManager.OpenExeConfiguration(exeConfigPath); 

這樣做是因爲該庫已加載其捆綁的配置,而不是應用程序配置。應用程序配置不應該關心庫的設置,不應該能夠改變它們。

現在,還有一些其他事情需要完成這個概念的工作。我必須將庫的配置文件構建操作設置爲屬性窗口中的內容,並將副本設置爲Copy AlwaysCopy If Newer。到目前爲止,文件自動進入到類庫的bin目錄和web應用程序的bin目錄中,並且從App.config正確地重命名爲CustomLibrary.dll.config(假定庫的DLL是CustomLibrary.dll)。

現在我面臨兩個問題。

1)當我將Web應用程序發佈到文件系統位置(映射到IIS)時,CustomLibrary.dll.config在發佈的應用程序的bin文件夾中顯示爲App.config。好的 - 我將在類庫項目中重命名它以符合預期的約定 - 並解決問題。

2)即使發佈,IIS也會再次編譯應用程序並將其存儲在ASP.NET Temporary Files中。有一個花哨的目錄結構,其中包含專用於每個組件的文件夾。與CustomLibrary.dll相對應的文件夾不包含其中的配置文件。由於this.GetType().Assembly.Location將返回到臨時文件夾的路徑,應用程序無法加載配置並崩潰,因爲它應該。

我需要保留在類庫中具有配置的模式,並且能夠使其在Web應用程序中工作。手動將.config複製到臨時文件夾時,該應用程序可以正常工作,但請參閱,我真的很討厭手動複製到隨機命名的文件夾。

有沒有辦法阻止IIS使用臨時文件夾,或使它沿着配置文件複製?我相信我面臨的問題是配置相關而不是概念性的,因爲當配置文件就位時應用程序按預期工作。我寧願不要亂用配置文件的硬編碼物理路徑。


編輯:

使其更清晰,我會指出什麼,爲什麼我想要實現。這個想法是,庫和Web項目將作爲獨立的產品開發 - 在庫的配置中不會有用戶或應用程序特定的信息,因此不會因不同的使用場景而改變。它也是特定於類庫功能而不是最終應用程序。對我來說,保持庫中的配置信息是合理的(類似於Java,其中spring上下文xml文件或屬性文件與庫的jar捆綁在一起)。我想避免必須複製消費者應用程序的每個app/web配置中的配置。有些情況下,消費者應用程序是由第三方開發的,我不想依賴於他們配置我的東西的權利工作。同樣,這裏唯一的問題是沒有將配置文件複製到正確的位置。

+0

這就是.NET一直以來的工作原理。您需要從類庫配置文件複製設置並將它們粘貼到web.config中。 – 2013-03-15 01:15:30

+0

我明白了,我仍然相信自己已經非常接近我需要實現的目標(請參閱我的重訪帖子,瞭解我的原因)。唯一的攔截器是文件不被臨時文件夾中的IIS複製。 – 2013-03-15 08:59:04

回答

1

如果這些都是靜態的,那麼任何人都不應該看到或更改的內部設置,那麼將類型庫中包含的配置作爲嵌入式資源的文件不是更好嗎?無論是那個或只是一個靜態類的設置。

這樣你就可以確定沒有人改變它,這在你的場景中似乎是一個加號。

+0

好主意!我已經將配置文件標記爲嵌入式資源(複製總是不再需要),我只是將其提取到臨時文件夾,並使用'ConfigurationManager.OpenMappedExeConfiguration(exeConfigPath,....)'加載它' – 2013-03-16 13:49:38

+0

注意:一個重要的缺點是配置會在程序集內編譯,爲使更改生效,庫必須重新構建,但在這一點上這不是我關心的問題。另外,應用程序應該能夠寫入OS臨時文件夾,以便將配置保存爲物理文件,因爲無法將其作爲流加載。 – 2013-03-16 13:52:27

+1

正確。但是,您有另一種選擇,即不使用配置API,而是直接從嵌入式資源將XML反序列化爲對象模型。這樣你就避免了需要對文件系統進行寫訪問,處理臨時文件夾等問題。 – 2013-03-16 23:18:38

0

簡短的回答是:你不能。您必須合併兩個配置部分,並將所有設置放在應用程序的主配置文件中。在web應用程序中,它將是web.config。閱讀this

+0

這正是我想要避免的 - 請參閱我的帖子的重訪細節。事實上,上面的代碼只是我想要的方式,問題是在臨時asp.net文件中缺少的配置 – 2013-03-15 22:30:22

1

我已經出現了一種圍繞所述問題開展工作的方式,對我的要求來說仍然不是一件令人愉快的事情。

解決方案是利用始終可用的應用程序配置(Web應用程序中的web.config或app.config)。我已經爲設置添加了每個庫的配置文件的絕對路徑。所以我結束了:

<!-- 
THIS IS IN THE WEB.CONFIG FILE 
--> 
<appSettings> 
    <add key ="ClassLibrary_ConfigPath" 
     value ="{My Publish Output Folder}\ClassLibrary.dll.config"/> 
</appSettings> 

和類庫現在使用下面的代碼加載其配置:

Configuration config = null; 
try 
{ 
    var exeConfigPath = this.GetType().Assembly.Location; 
    config = ConfigurationManager.OpenExeConfiguration(exeConfigPath); 
} 
catch (Exception e) 
{ 
    if (!IsConfigurationNotFoundError(e)) 
    { 
     // IsConfigurationNotFoundError logic skipped for brevity 
     var exeConfigPath = 
      ConfigurationManager.AppSettings["ClassLibrary_ConfigPath"]; 
     if (exeConfigPath != null) 
     { 
      config = ConfigurationManager.OpenExeConfiguration(exeConfigPath); 
     } 
    } 
    else 
    { 
     throw; 
    } 
} 

雖然這個作品,我會等待,如果可能的一個更好的解決方案。不過,我不必將整個ClassLibrary.dll.config複製到web.config文件中,但現在我必須管理文件系統位置並瞭解應用程序設置名稱。我真正想要的是ClassLibrary.dll的消費者應用程序不以任何方式處理其配置。如果它是一個桌面應用程序,我已經介紹了這一點,因爲Visual Studio會正確地複製ClassLibary.dll.config。我希望有一種方法可以使Web應用程序順利運行。