假设我正在创建一个名为ConsoleApp2的应用程序。
由于我正在使用某些第三方库,因此我的默认app.config文件正在生成类似
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly>
<assemblyIdentity name="Newtonsoft.Json" publicKeyToken="30ad4fe6b2a6aeed" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-12.0.0.0" newVersion="12.0.0.0" />
</dependentAssembly>
</assemblyBinding>
</runtime>
那是因为我的解决方案引用了一个库的不同版本,因此它需要告诉所有人:“嘿,如果您要查找该库的任何oldVersion,请使用newVersion”。没关系。
问题是我想定义一个单独的配置文件“ test.exe.config”,其中我有一些设置并摆脱了自动生成的配置文件。
为了告诉我的应用有关新配置文件的信息,我正在使用类似以下代码
AppDomain.CurrentDomain.SetData("APP_CONFIG_FILE", "test.exe.config");
并且(几乎)完美地工作。我写了“差不多”的字样,因为尽管<appSettings>
部分已被正确读取,但<runtime>
部分并未在我的自定义配置文件中查看,但App会在默认配置文件中查找它,这是一个问题,因为我希望以后可以删除那个。
那么,如何告诉我的应用程序也从我的自定义配置文件中读取<runtime>
信息?
如何重现问题
重现我的问题的一个简单示例如下:
创建具有单个类的名为ClassLibrary2(.Net Framework v4.6)的库,如下所示
using Newtonsoft.Json.Linq;
using System;
namespace ClassLibrary2
{
public class Class1
{
public Class1()
{
var json = new JObject();
json.Add("Succeed?", true);
Reash = json.ToString();
}
public String Reash { get; set; }
}
}
请注意对Newtonsoft包的引用。库中安装的是v10.0.2。
现在使用名为Program的类创建一个名为ConsoleApp2(.Net Framework v4.6)的控制台应用程序,其内容如下:
using System;
using System.Configuration;
namespace ConsoleApp2
{
class Program
{
static void Main(string[] args)
{
AppDomain.CurrentDomain.SetData("APP_CONFIG_FILE", "test.exe.config");
var AppSettings = ConfigurationManager.AppSettings;
Console.WriteLine($"{AppSettings.Count} settings found");
Console.WriteLine($"Calling ClassLibrary2: {Environment.NewLine}{new ClassLibrary2.Class1().Reash}");
Console.ReadLine();
}
}
}
该应用程序还应该安装了Newtonsoft,但版本为v12.0.3。
在调试模式下生成应用程序。然后,在ConsoleApp2 / ConsoleApp2 / bin / Debug文件夹中,创建一个名为test.exe.config的文件,其内容如下
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.6" />
</startup>
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly>
<assemblyIdentity name="Newtonsoft.Json" publicKeyToken="30ad4fe6b2a6aeed" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-12.0.0.0" newVersion="12.0.0.0" />
</dependentAssembly>
</assemblyBinding>
</runtime>
<appSettings>
<add key="A" value="1"/>
<add key="B" value="1"/>
<add key="C" value="1"/>
</appSettings>
</configuration>
并注意,在同一Debug文件夹中,还存在默认配置文件ConsoleApp2.exe.config,其内容类似于
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.6" />
</startup>
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly>
<assemblyIdentity name="Newtonsoft.Json" publicKeyToken="30ad4fe6b2a6aeed" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-12.0.0.0" newVersion="12.0.0.0" />
</dependentAssembly>
</assemblyBinding>
</runtime>
</configuration>
如果此时您运行该应用程序,它将毫无问题地进行编译,您应该会看到一个类似
请注意,正确地从我的自定义配置文件中读取了(3)设置。到目前为止,一切都很好...
现在,将默认配置文件重命名为_ConsoleApp2.exe.config之类,然后再次运行该应用程序。您现在应该获得FileLoadException。
因此,我又该如何告诉我的应用程序从我的自定义配置文件中读取<runtime>
信息?
基本原理
我正在寻找此问题的答案的原因如下:
当我们发布应用程序时,我们将所有.exe和.dll文件放在一个文件夹中,而将自定义配置文件(带有设置等)放在另一个文件夹中,客户端的文件与此类似。
在包含.exe和.dll文件的文件夹中,我们尝试将其保留得尽可能少,因此,如果可能,我被要求找到一种摆脱该ConsoleApp2.exe.config的方法。现在,由于上述绑定是写在该配置文件中的,所以我只是尝试将这些信息移到我们的自定义配置文件中...但是到目前为止,我仍未能实现:总是尝试从该ConsoleApp2.exe中读取绑定重定向。 .config,因此,一旦我将其删除,就会出现异常...
参考方案
您可能正在寻找配置转换:
背后的想法是,您可以在Visual Studio中创建多个配置,例如配置管理器中的“调试”,“发布”,“生产”,“测试...”和默认配置文件以及所谓的“转换”。
请注意,您可以在配置管理器中创建任意数量的配置。要添加新的,请单击“解决方案配置”(显示“ Debug”或“ Release”的下拉菜单),然后选择“ Configuration Manager ...”。打开它,您会看到所有当前现有配置的列表。下拉组合框“活动解决方案配置”,然后选择“ <New...>
”添加更多内容。
这些转换指定了使特定配置与默认配置不同的原因-因此您无需重复在默认配置中已经指定的配置,而只需提及不同之处,例如:
<configuration>
<appSettings>
<add key="ClientSessionTimeout" value="100"
xdt:Transform="SetAttributes" xdt:Locator="Match(key)" />
</appSettings>
</configuration>
它通过其键ClientSessionTimeout
找到相关设置,并通过替换配置文件中的原始值将其值设置为100
(这是附加转换属性xdt:Transform="SetAttributes" xdt:Locator="Match(key)"
的含义)。您还可以指定删除现有设置(通过指定xdt:Transform="Remove"
代替),例如
<add key="UserIdForDebugging" xdt:Transform="Remove" xdt:Locator="Match(key)"/>
将会删除仅用于调试而非发布的用户ID(要了解有关可用选项的更多信息,请查看here-为Web.config所描述,但也适用于App.config)。
除了App.Config
文件之外,每种配置还具有一个文件,即App.Debug.Config
用于调试,App.Release.Config
用于发行等。VisualStudio可以帮助您创建它们。
我已经在StackOverflow here和there中创建了答案,详细描述了它,请看一下。
如果在Visual Studio中显示它们时遇到问题,请查看here。
关于您的理由:
转换通过将转换文件应用于默认配置文件来创建完整的配置文件。将编译生成的文件,并将其与其他编译文件一起放入“ bin”文件夹中。因此,如果选择了配置“发布”,则所有文件(包括转换后的配置文件)都将编译为“ bin \ Release”。
并且配置文件的名称与exe文件的名称以及末尾附加的“ .config”相同(换句话说,二进制文件夹中没有“ .Release.config”,但是创建了“ MySuperCoolApp.exe.config”)-应用程序“ MySuperCoolApp.exe”)。
同样,其他配置也是如此-每个配置都在“ bin”中创建一个子文件夹-如果您使用的是脚本,则该子文件夹在构建后事件中可以引用为$(TargetDir)
。
我正在使用带有ajax的jquery。有时,给出错误$未定义。这是我的代码:<script language="javascript" type="text/javascript"> var base_path="<? echo $this->baseUrl().'/…
如何以编程方式扩展Jquery Slider Panel? - c#我有用于登录的JQuery Silder面板|注册选项。供参考,我已包含此滑块Jquery Login | Register Slider Panel的演示实际的问题是,当位于“文字”控件中的“登录”部分或“注册新帐户”部分中有值时,如何以编程方式扩展此滑块。为了理解这个问题,我把我的设计代码。 <asp:Panel ID="Panel_Lo…
Div单击与单选按钮相同吗? - php有没有一种方法可以使div上的click事件与表单环境中的单选按钮相同?我只希望下面的div提交值,单选按钮很丑代码输出如下:<input id="radio-2011-06-08" value="2011-06-08" type="radio" name="radio_date…
故障排除“警告:session_start():无法发送会话高速缓存限制器-标头已发送” - php我收到警告:session_start()[function.session-start]:无法发送会话缓存限制器-标头已发送(错误输出开始如果我将表单数据提交到其他文件进行处理,则可以正常工作。但是,如果我将表单数据提交到同一页面,则会出现此错误。请建议<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0…
Java中的<<或>>>是什么意思? - javaThis question already has answers here: Closed 7 years ago. Possible Duplicate: What does >> and >>> mean in Java?我在一些Java代码中遇到了一些陌生的符号,尽管代码可以正确编译和运行,但对于括号在此代码中的作用却感…