我已經爲Outlook 2010-2016創建了Outlook插件與Visual Studio 2013. Outlook加載項包含2個WPF表單利用REST api並執行http休息調用。結果是Json,並且會被Newtonsoft Json反序列化。內部使用的Outlook插件的WPF窗體中使用的Newtonsoft Json未找到應用程序配置
在調試模式下,一切正常。 只要我用wix創建安裝工具並安裝加載項,我就得到了Json對象不再被反序列化的問題。原因是加載項沒有找到配置文件。 我發現Outlook在Office Outlook程序路徑中查找了outlook.exe.config。但這不是我想要的,因爲我不想在可能影響其他應用程序的中央配置文件中進行任何更改。
搞清楚這之後,我發現這個整潔的小代碼段來更改配置文件在我的加載的啓動:
using System;
using System.Configuration;
using System.Linq;
using System.Reflection;
public abstract class AppConfig : IDisposable
{
public static AppConfig Change(string path)
{
return new ChangeAppConfig(path);
}
public abstract void Dispose();
private class ChangeAppConfig : AppConfig
{
private readonly string oldConfig =
AppDomain.CurrentDomain.GetData("APP_CONFIG_FILE").ToString();
private bool disposedValue;
public ChangeAppConfig(string path)
{
AppDomain.CurrentDomain.SetData("APP_CONFIG_FILE", path);
ResetConfigMechanism();
}
public override void Dispose()
{
if (!disposedValue)
{
AppDomain.CurrentDomain.SetData("APP_CONFIG_FILE", oldConfig);
ResetConfigMechanism();
disposedValue = true;
}
GC.SuppressFinalize(this);
}
private static void ResetConfigMechanism()
{
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);
}
}
}
改變應用程序配置到我可以讀取所有正確的路徑後通過System.Configuration.ConfgurationManager從配置文件中取出設置(我在安裝發行版後在運行時嘗試過,並將它寫出到文件流中)。
但仍...試圖將JSON反序列化到一個對象,我得到以下錯誤時:
System.IO.FileLoadException: Could not load file or assembly 'Newtonsoft.Json, Version=4.5.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed' or one of its dependencies. The located assembly's manifest definition does not match the assembly reference. (Exception from HRESULT: 0x80131040) File name: 'Newtonsoft.Json, Version=4.5.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed' at System.Net.Http.Formatting.JsonMediaTypeFormatter..ctor() at System.Net.Http.Formatting.MediaTypeFormatterCollection.CreateDefaultFormatters() at XXXXXXXXXXXXXXXX.<>c__DisplayClass16.b__14(Task`1 task)
=== Pre-bind state information === LOG: DisplayName = Newtonsoft.Json, Version=4.5.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed (Fully-specified) LOG: Appbase = file:///C:/Program Files/XXXXXXXXX/ LOG: Initial PrivatePath = NULL Calling assembly : System.Net.Http.Formatting, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35. === LOG: This bind starts in default load context. LOG: No application configuration file found. LOG: Using host configuration file: LOG: Using machine configuration file from C:\Windows\Microsoft.NET\Framework\v4.0.30319\config\machine.config. LOG: Post-policy reference: Newtonsoft.Json, Version=4.5.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed LOG: Attempting download of new URL file:///C:/Program Files/XXXXXX/Newtonsoft.Json.DLL. WRN: Comparing the assembly name resulted in the mismatch: Major Version ERR: Failed to complete setup of assembly (hr = 0x80131040). Probing terminated.
這是我的app.config文件看起來像:
<?xml version="1.0" encoding="utf-8"?>>
<configuration>
<appSettings>
<add key="ApiUrl" value="http://localhost:56610/api" />
</appSettings>
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly>
<assemblyIdentity name="Newtonsoft.Json" publicKeyToken="30ad4fe6b2a6aeed" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-9.0.0.0" newVersion="9.0.0.0" />
</dependentAssembly>
</assemblyBinding>
</runtime>
</configuration>
有誰知道爲什麼Newtonsoft Json的配置不起作用,爲什麼我提供的配置沒有使用?
非常感謝您的幫助。