Office 2013/2016中的C#SerializationException VSTO加载项与CSLA

时间:2017-08-30 08:04:11

标签: c# vsto csla

我在CSLA论坛上第一次asked for help,但我还没能解决这个问题。我创建了一个test VS2015 solution来演示我遇到的问题。

我在Outlook,Word,Excel和PowerPoint中使用CSLA 4.6.603。设置Csla.ApplicationContext.User后,在显示SerializationExceptionForm或甚至阅读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

读取XML时抛出相同的dataSet.ReadXml(tempFileName, XmlReadMode.InferSchema);

我正在处理AppDomain.CurrentDomain.AssemblyResolve事件,并且在抛出异常之前就在AppDomain.CurrentDomain.GetAssemblies()中列出了CSLA。

测试解决方案有一个非常基本的自定义标识,一个从生成的XML文件中读取的基本业务对象,以及一个带有三个按钮的表单。

如果将WindowsUI项目设置为StartUp项目并运行它,则主窗体中的每个按钮都应该成功,不会抛出任何异常。

将WordAddIn项目设置为StartUp项目并运行它。 Word启动,相同的表单显示为加载项加载。第一个按钮成功,但接下来的两个按钮会抛出异常。有关详细信息,请参阅调试输出,或设置断点。对于OutlookAddIn项目也是如此。

正如其他人早先在CSLA论坛帖子中指出的那样,这是由.NET无法解决程序集引起的或与之相关的。 AssemblyResolve事件可能就是答案,我只是无法弄明白。

非常感谢任何帮助。

1 个答案:

答案 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解决了这个问题。根本不需要解决方法。这是最后的手段,但到目前为止它看起来是唯一可靠的解决方案。