【问题标题】:Is there any way to initialize the web.config in C# interactive?有什么方法可以在 C# 交互中初始化 web.config 吗?
【发布时间】:2018-04-27 05:14:19
【问题描述】:

我有一个目前正在处理的 ASP.NET MVC 项目。我想在 C# 交互中尝试一些代码,我单击“初始化与项目交互”。我可以在 c# 交互中看到变量、类和其他东西。

现在有一个问题是通过 web.config 定义的静态变量抛出异常。

如果我粘贴使用 web.config 变量的代码(在交互式窗口中)不起作用。无论如何要解决这个问题。

我检查了 SeM 的答案,我检查了 appsettings 它什么都没有

更新 2:

我在 github 上设置了代码,并按照答案中给出的阅读 appsettings,仍然没有工作,代码在这里 https://github.com/anirugu/CsharpInteractiveTesting

【问题讨论】:

  • 是什么阻止您在代码中定义静态变量?另外,它会抛出什么异常?
  • 如果我执行代码,它会说“'abc.Globals' 的类型初始化程序引发了异常。”

标签: c# interactive


【解决方案1】:

C# 交互本身作为具有单独应用程序配置文件的单独应用程序运行。如果你在 C# 交互中运行它:

AppDomain.CurrentDomain.SetupInformation.ConfigurationFile

你会看到类似的东西:

"<path to VS>\\CommonExtensions\\Microsoft\\ManagedLanguages\\VBCSharp\\InteractiveComponents\\InteractiveHost.exe.Config"

这就是正在使用的配置文件。当然它不包含您的变量,因此尝试执行 ConfigurationManager.AppSettings["foo"].ToString() 的代码会失败。

在运行时设置配置文件的常用方法是:

AppDomain.CurrentDomain.SetData("APP_CONFIG_FILE", fullPathToYourConfig);

但是,这应该在对配置文件进行任何访问之前完成。首次访问时 - 正在缓存文件,随后对路径的更改将无效。不幸的是,在允许您访问执行命令之前,C# 交互式已经可以使用该文件。

有各种通过反射来重置缓存的技巧。例如(从here逐字复制):

public static void ChangeConfigTo(string path)
{
    AppDomain.CurrentDomain.SetData("APP_CONFIG_FILE", path);
    typeof(ConfigurationManager)
        .GetField("s_initState", BindingFlags.NonPublic |
            BindingFlags.Static)
        .SetValue(null, 0);

    typeof(ConfigurationManager)
        .GetField("s_configSystem", BindingFlags.NonPublic |
            BindingFlags.Static)
        .SetValue(null, null);

    typeof(ConfigurationManager)
        .Assembly.GetTypes()
        .Where(x => x.FullName ==
            "System.Configuration.ClientConfigPaths")
        .First()
        .GetField("s_current", BindingFlags.NonPublic |
            BindingFlags.Static)
        .SetValue(null, null);
}

考虑到所有这些,如果您将该函数放在 github 上示例中的 Program 类中,并在 C# 交互中执行此操作:

Program.ChangeConfigTo(Path.GetFullPath("app.config"));

您的代码将按预期工作。您可以将此 hack 放在单独的脚本 (.csx) 文件中,并在必要时使用“#load”加载它。

【讨论】:

    【解决方案2】:

    例如,如果您将设置添加到配置文件中

    <appSettings>
        <add key="Test" value="Test"/>
    </appSettings>
    

    并尝试通过ConfigurationManager读取它,它会抛出缺少引用的异常或

    当前上下文中不存在名称“ConfigurationManager”

    在 C# 交互式窗口中,您可以使用关键字 #r 引用程序集

    #r "System.Configuration"
    

    然后你可以得到你的价值:

    #r "System.Configuration"
    var settings = ConfigurationManager.OpenExeConfiguration(@"bin\Debug\YourAppName.dll"); //You can use .exe files too
    Console.WriteLine(settings.AppSettings.Settings["Test"].Value);
    

    还有!您可以通过右键单击您的项目 -> Initialize Interactive with Projcet 添加项目的所有引用,VS 将为您完成所有工作。

    更新

    对于your example

    using System.Configuration;
    var settings = ConfigurationManager.OpenExeConfiguration(@"D:\TestProjects\CsharpInteractiveTesting-master\CsharpInteractiveTesting-master\CsharpInteractiveTesting\bin\Debug\CsharpInteractiveTesting.exe");
    Console.WriteLine(settings.AppSettings.Settings["foo"].Value);
    

    【讨论】:

    • 在 ASP.NET MVC 5 中,我尝试初始化交互,当我读取值时它抛出异常“'abc.Globals' 的类型初始化器抛出异常。”
    • 请检查TypeInitializationExceptionInnerException 属性,它会告诉你更多关于你的异常。
    • 我用一张图片更新了这个问题,看起来好像没有从 web.config 初始化任何东西 无论如何要在 c# 交互中获得这些值,或者我错过了完成这件事的一部分。
    • @Adrian 请发布文字,而不是图片。
    • @Adrian 我用 github 链接更新了这个问题,还是不行。
    猜你喜欢
    • 2016-05-11
    • 2021-08-03
    • 1970-01-01
    • 2012-05-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-01-02
    相关资源
    最近更新 更多