我在CSLA论坛上第一次asked for help,但我还没能解决这个问题。我创建了一个test VS2015 solution来演示我遇到的问题。
我在Outlook,Word,Excel和PowerPoint中使用CSLA 4.6.603。设置Csla.ApplicationContext.User
后,在显示SerializationException
或Form
或甚至阅读XML时,可能会抛出MessageBox
。
问题的最简单的例子如下:
private void MessageThrows(object sender, EventArgs e)
{
// This message displays correctly
MessageBox.Show("About to set user to UnauthenticatedPrincipal. " +
"Check Debug Output to see exception.",
"Before UnauthenticatedPrincipal");
// The user is set correctly with no exception
Csla.ApplicationContext.User = new Csla.Security.UnauthenticatedPrincipal();
try
{
// The following message throws:
// System.Runtime.Serialization.SerializationException:
// Type is not resolved for member 'Csla.Security.UnauthenticatedPrincipal,Csla,
// Version =4.6.603.0,
// Culture =neutral,
// PublicKeyToken =93be5fdc093e4c30'.
MessageBox.Show("The user has been set to UnauthenticatedPrincipal.",
"After UnauthenticatedPrincipal");
}
catch (Exception ex)
{
Debug.WriteLine(ex);
}
}
在测试解决方案中,有另一个示例在尝试通过SerializationException
dataSet.ReadXml(tempFileName, XmlReadMode.InferSchema);
我正在处理AppDomain.CurrentDomain.AssemblyResolve
事件,并且在抛出异常之前就在AppDomain.CurrentDomain.GetAssemblies()
中列出了CSLA。
测试解决方案有一个非常基本的自定义标识,一个从生成的XML文件中读取的基本业务对象,以及一个带有三个按钮的表单。
如果将WindowsUI项目设置为StartUp项目并运行它,则主窗体中的每个按钮都应该成功,不会抛出任何异常。
将WordAddIn项目设置为StartUp项目并运行它。 Word启动,相同的表单显示为加载项加载。第一个按钮成功,但接下来的两个按钮会抛出异常。有关详细信息,请参阅调试输出,或设置断点。对于OutlookAddIn项目也是如此。
正如其他人早先在CSLA论坛帖子中指出的那样,这是由.NET无法解决程序集引起的或与之相关的。 AssemblyResolve
事件可能就是答案,我只是无法弄明白。
非常感谢任何帮助。
答案 0 :(得分:0)
在Ingo on CSLA论坛的帮助下,我认为我们找到了解决方法。
private void ThisAddIn_Startup(object sender, System.EventArgs e)
{
Csla.ApplicationContext.PropertyChangedMode = Csla.ApplicationContext.PropertyChangedModes.Windows;
Csla.ApplicationContext.ContextManager = new Csla.Windows.ApplicationContextManager();
// Workaround to prevent 'SerializationException' in VSTO add-in
// 1. Force initialisation of ConfigurationManager
System.Configuration.ConfigurationManager.GetSection("Dummy");
// 2. Set UnauthenticatedPrincipal explicitly after
// setting the Csla.ApplicationContextManager
Csla.ApplicationContext.User = new Csla.Security.UnauthenticatedPrincipal();
}
我发现在任何功能区控件事件处理程序显示任何UI之前,我们需要重新运行变通代码,并重新分配当前用户就足够了。它看起来很荒谬,但它确实有效。
/// <summary>
/// Microsoft Office add-ins can experience
/// <code>System.Runtime.Serialization.SerializationException</code>
/// "Type is not resolved for member Csla.Security.UnauthenticatedPrincipal".
/// Calling this method before showing any UI works around the problem.
/// </summary>
public static void ExceptionWorkaround(bool setUnauthenticatedPrincipal = false)
{
// 1. Force initialisation of ConfigurationManager
ConfigurationManager.GetSection("Dummy");
// 2. Set User explicitly
if (setUnauthenticatedPrincipal)
Csla.ApplicationContext.User = new UnauthenticatedPrincipal();
else
Csla.ApplicationContext.User = Csla.ApplicationContext.User;
}
<强>更新强>
我找到了此解决方法失败的其他方案。在GAC中安装Csla.dll解决了这个问题。根本不需要解决方法。这是最后的手段,但到目前为止它看起来是唯一可靠的解决方案。