web-dev-qa-db-ja.com

物理パスでOpenWebConfigurationを作成する方法は?

IIS7にサイトを作成するwinフォームがあります。 1つの関数は、web.configファイルを開き、いくつかの更新を行う必要があります。 (接続文字列、smtp、なりすまし)

ただし、仮想パスはなく、物理パスしかありません。

WebConfigurationManagerをまだ使用できる方法はありますか?

セクションを見つけて読み書きする機能を使用する必要があります。

System.Web.Configuration.WebConfigurationManager.OpenWebConfiguration
35
aron

PhysicalPathをvirtualPathにマップする必要があります。これがあなたのやり方です。

using System.Web.Configuration;  //Reference the System.Web DLL (project needs to be using .Net 4.0 full, not client framework)

public static Configuration OpenConfigFile(string configPath)
{
    var configFile = new FileInfo(configPath);
    var vdm = new VirtualDirectoryMapping(configFile.DirectoryName, true, configFile.Name);
    var wcfm = new WebConfigurationFileMap();
    wcfm.VirtualDirectories.Add("/", vdm);
    return WebConfigurationManager.OpenMappedWebConfiguration(wcfm, "/");
}
66
Vadim Rybak

ヴァディムの答えは私たちの開発サーバーではうまくいきましたが、次のメッセージで私たちのライブサーバーに爆撃しました:

System.ArgumentOutOfRangeException: Specified argument was out of the range of valid values. Parameter name: site 

これを修正するために、IIS Webサイト名を3番目のパラメーターとして受け取るWebConfigurationManager.OpenMappedWebConfigurationの別のオーバーロードを見つけました。結果は次のとおりです。

public static Configuration OpenConfigFile(string configPath)
{
    var configFile = new FileInfo(configPath);
    var vdm = new VirtualDirectoryMapping(configFile.DirectoryName, true, configFile.Name);
    var wcfm = new WebConfigurationFileMap();
    wcfm.VirtualDirectories.Add("/", vdm);
    return WebConfigurationManager.OpenMappedWebConfiguration(wcfm, "/", "iis_website_name");
}
10
Keith

ヴァディムの答えに基づいて、彼が書いたものは私の状況では正確に機能しないことがわかったので、代わりにこれを使用しました:

Dim connectionSettings As New ConnectionStringSettings("mySQLite", ConnectionStringHelper.MyConnectionString)

Dim dummyVirtualPath As String = "/MyApp"
Dim virtualDirMap = New VirtualDirectoryMapping(Server.MapPath("~"), True)
Dim webConfigFileMap = New WebConfigurationFileMap()
webConfigFileMap.VirtualDirectories.Add(dummyVirtualPath, virtualDirMap)
Dim mappedConfigFile = WebConfigurationManager.OpenMappedWebConfiguration(webConfigFileMap, dummyVirtualPath)

Dim config As System.Configuration.Configuration = mappedConfigFile WebConfigurationManager.OpenWebConfiguration(Server.MapPath("~") & "/")
Dim csSection As ConnectionStringsSection = config.ConnectionStrings

If csSection.ConnectionStrings("mySQLite") IsNot Nothing AndAlso csSection.ConnectionStrings("mySQLite").ConnectionString <> connectionSettings.ConnectionString Then
    csSection.ConnectionStrings("mySQLite").ConnectionString = connectionSettings.ConnectionString
    config.Save()
    ConfigurationManager.RefreshSection(csSection.SectionInformation.Name)
End If

他の誰かが私がやろうとしていることを試みてこれを見つけた場合、これを行う目的は、SimpleMembershipProviderから継承するExtendedMembershipProviderをSQLiteで動作させることでした。それを行うために、このリンクごとに手動でテーブルを作成しました: SimpleMembershipProvider in MVC4 、そしてこのコマンドをGlobal.asaxファイルのApplication_Startルーチン:

WebSecurity.InitializeDatabaseConnection(ConnectionStringHelper.MyConnectionString, "System.Data.SQLite", "Users", "UserID", "Email", False)

結局のところ、実際にweb.configファイルを書き換える必要はまったくありませんでした。 (私がしなければならなかった多くのweb.configの変更もありましたが、それはこの質問の範囲外です。)

0
cjbarth

ヴァディムの答えはまさに私が必要とするものでしたが、私はキースと同じ問題に遭遇しました、そして彼の解決策はトリックをしました!

ただし、IIS Webサイト名は 呼び出しによって取得

System.Web.Hosting.HostingEnvironment.ApplicationHost.GetSiteName();

また、cjbarthのコードには、wwwrootとWeb.configの場所が異なる可能性がある環境でのテストのための整然としたソリューションが含まれていました。

System.Web.HttpContext.Current.Server.MapPath("~");

これらを念頭に置いて、ヴァディムの機能をもう少し改善すると、次のようになります。

    public static Configuration GetWebConfig() {
        var webConfigFile = new FileInfo("Web.config");
        var wwwRootPath = HttpContext.Current.Server.MapPath("~");
        var vdm = new VirtualDirectoryMapping(wwwRootPath, true, webConfigFile.Name);
        var wcfm = new WebConfigurationFileMap();
        wcfm.VirtualDirectories.Add("/", vdm);
        var siteName = HostingEnvironment.ApplicationHost.GetSiteName();
        return WebConfigurationManager.OpenMappedWebConfiguration(wcfm, "/", siteName);
    }
0
Fehr