我一直在使用的一个应用程序在尝试序列化类型时失败了。

像这样的陈述

XmlSerializer lizer = new XmlSerializer(typeof(MyType));

生产:

System.IO.FileNotFoundException occurred
  Message="Could not load file or assembly '[Containing Assembly of MyType].XmlSerializers, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null' or one of its dependencies. The system cannot find the file specified."
  Source="mscorlib"
  FileName="[Containing Assembly of MyType].XmlSerializers, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null"
  FusionLog=""
  StackTrace:
       at System.Reflection.Assembly._nLoad(AssemblyName fileName, String codeBase, Evidence assemblySecurity, Assembly locationHint, StackCrawlMark& stackMark, Boolean throwOnFileNotFound, Boolean forIntrospection)
       at System.Reflection.Assembly.nLoad(AssemblyName fileName, String codeBase, Evidence assemblySecurity, Assembly locationHint, StackCrawlMark& stackMark, Boolean throwOnFileNotFound, Boolean forIntrospection)

我没有为我的类定义任何特殊的序列化器。

我该如何解决这个问题?


当前回答

此异常也可以由名为BindingFailure的托管调试助手(MDA)捕获。

如果您的应用程序被设计为附带预构建序列化程序集,则此MDA非常有用。这样做是为了提高应用程序的性能。它允许我们确保预先构建的序列化程序集由构建过程正确构建,并由应用程序加载,而无需动态重新构建。

除了在这种情况下,它实际上没什么用,因为正如其他帖子所说,当绑定错误被Serializer构造函数捕获时,序列化程序集将在运行时重新构建。所以你可以把它关掉。

其他回答

在Visual Studio项目属性(“Build”页面,如果我没记错的话)中有一个选项显示“生成序列化程序集”。尝试为生成[包含MyType的程序集]的项目打开该选项。

我也遇到了类似的问题,忽略这个异常对我不起作用。我的代码调用NServiceBus的配置configuration . with(…).XmlSerializer()…

对我来说,解决这个问题的方法是改变我项目的平台。

去构建\配置管理器… 找到你的项目并更改平台(在我的情况下,从x86到任何CPU)

信不信由你,这是正常行为。抛出一个异常,但由XmlSerializer处理,因此如果忽略它,一切都应该继续正常进行。

我发现这非常烦人,如果你搜索一下,会有很多抱怨,但据我所知,微软并不打算对此采取任何措施。

如果关闭特定异常的第一次机会异常,就可以避免在调试时一直弹出异常。在Visual Studio中,打开调试->异常(或按Ctrl + Alt + E),公共语言运行时异常->系统。IO -> System.IO.FileNotFoundException。

您可以在博客文章c# XmlSerializer FileNotFound异常(其中讨论了Chris Sells的工具XmlSerializerPreCompiler)中找到关于另一种方法的信息。

我的解决方案是直接使用反射来创建序列化器。这就绕过了导致异常的奇怪文件加载。我将其打包在一个helper函数中,该函数还负责缓存序列化器。

private static readonly Dictionary<Type,XmlSerializer> _xmlSerializerCache = new Dictionary<Type, XmlSerializer>();

public static XmlSerializer CreateDefaultXmlSerializer(Type type) 
{
    XmlSerializer serializer;
    if (_xmlSerializerCache.TryGetValue(type, out serializer))
    {
        return serializer;
    }
    else
    {
        var importer = new XmlReflectionImporter();
        var mapping = importer.ImportTypeMapping(type, null, null);
        serializer = new XmlSerializer(mapping);
        return _xmlSerializerCache[type] = serializer;
    }
}

Martin Sheburn最初的回答是正确的。 来自edeboursetty, tomas-kubes)的代码示例,quadfinity应该解决在调试器中不引发过量异常的问题。

这里有一个简短的解决方案:

internal sealed static class XmlSerializerHelper
{
    private static readonly ConcurrentDictionary<Type, System.Xml.Serialization.XmlSerializer> s_xmlSerializers = new();

    public static System.Xml.Serialization.XmlSerializer Get<T>()
    {
        return s_xmlSerializers.GetOrAdd(typeof(T), _ => System.Xml.Serialization.XmlSerializer.FromTypes(new [] {typeof(T)})[0]);
    }
}