394

An application I've been working with is failing when I try to serialize types.

A statement like

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

produces:

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)

I don't define any special serializers for my class.

How can I fix this problem?

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Irwin
  • 12,551
  • 11
  • 67
  • 97
  • 5
    OK, so this question is just my C# version of an already asked VB question: http://stackoverflow.com/questions/294659/why-did-i-get-an-error-with-my-xmlserializer Thanks guys. – Irwin Jul 14 '09 at 19:51
  • 2
    Six years on, @VladV 's answer is the simplest and the least adverse-affecting solution. Just change the `Generate serialization assembly` drop-down to "On", instead of "Auto". – Riegardt Steyn Jul 23 '15 at 12:02
  • @Heliac: I disagree. It does not always work. Please see Benoit Blanchon's comment to Vlad's answer. The simplest answer for me is to not use String.Collection in config files. Instead I use: string[] items = Settings.Default.StringofNewlineDelimitedItems.Split(new[] {Environment.NewLine}); – Andrew Dennison Dec 17 '15 at 19:44

21 Answers21

451

Believe it or not, this is normal behaviour. An exception is thrown but handled by the XmlSerializer, so if you just ignore it everything should continue on fine.

I have found this very annoying, and there have been many complaints about this if you search around a bit, but from what I've read Microsoft don't plan on doing anything about it.

You can avoid getting Exception popups all the time while debugging if you switch off first chance exceptions for that specific exception. In Visual Studio, go to Debug -> Exceptions (or press Ctrl + Alt + E), Common Language Runtime Exceptions -> System.IO -> System.IO.FileNotFoundException.

You can find information about another way around it in the blog post C# XmlSerializer FileNotFound exception (which discusses Chris Sells' tool XmlSerializerPreCompiler).

Moon Waxing
  • 695
  • 13
  • 19
Martin Sherburn
  • 5,958
  • 2
  • 23
  • 17
  • 178
    One of the possible ways to get rid of this problem is check "Just my code" option in Tools -> Options -> Debugging -> General options. – Frederic Mar 18 '10 at 10:42
  • 28
    @Frederic: This comment is awesome! I'm sitting here with a "WTF!?" expression on my face, trying to hunt this spurious exception down, and I find this question, with answer (It's Microsoft's fault, what else is new?), but I didn't want to disable exception handling, because I might need it for my code. A+! – Kumba Jan 04 '11 at 01:59
  • 1
    @Frederic > Your solution is far better. VoteUp! – Adi Mar 14 '11 at 07:54
  • It took some googling to find your answer. I was looking for a cause and it never occured to me to just ignore the exception and see what happens. I dont like libraries that use execptions for flow control. +1 though. :) – Mizipzor Apr 24 '12 at 10:23
  • 31
    I think Hans' suggestion below is more valuable - use a different method call that does not produce this exception at all: XmlSerializer serializer = XmlSerializer.FromTypes(new[] { typeof(MyType) })[0]; – bright Jun 09 '12 at 07:47
  • 3
    The problem is that this fails my test, so I cannot just "ignore" the exception – Csaba Toth Jun 28 '13 at 16:08
  • 19
    I'm sorry, but this is a terrible suggestion. FileNotFoundException is one of the more common ones, in my experience, and disabling this exception reporting is just asking for trouble someday in the future. Better to turn on 'Just My Code' or enable the creation of serialization assemblies described below. – Quark Soup Nov 22 '13 at 15:44
  • For me I have to turn off both System.IO.FileNotFoundException and Binding Failure in the Managed Debugging Assistants – HoKy22 Dec 05 '13 at 19:50
  • 2
    @DRAirey1: Sure, it is one of the more common ones; but is also one of the ones code can reasonably expect to fire and be expected to handle. There isn't a way to avoid IO-related exceptions in .NET. So long as the exception is caught, it shouldn't matter. – Billy ONeal May 31 '14 at 14:41
116

Like Martin Sherburn said, this is normal behavior. The constructor of the XmlSerializer first tries to find an assembly named [YourAssembly].XmlSerializers.dll which should contain the generated class for serialization of your type. Since such a DLL has not been generated yet (they are not by default), a FileNotFoundException is thrown. When that happenes, XmlSerializer's constructor catches that exception, and the DLL is generated automatically at runtime by the XmlSerializer's constructor (this is done by generating C# source files in the %temp% directory of your computer, then compiling them using the C# compiler). Additional constructions of an XmlSerializer for the same type will just use the already generated DLL.

UPDATE: Starting from .NET 4.5, XmlSerializer no longer performs code generation nor does it perform compilation with the C# compiler in order to create a serializer assembly at runtime, unless explicitly forced to by setting a configuration file setting (useLegacySerializerGeneration). This change removes the dependency on csc.exe and improves startup performance. Source: .NET Framework 4.5 Readme, section 1.3.8.1.

The exception is handled by XmlSerializer's constructor. There is no need to do anything yourself, you can just click 'Continue' (F5) to continue executing your program and everything will be fine. If you're bothered by the exceptions stopping the execution of your program and popping up an exception helper, you either have 'Just My Code' turned off, or you have the FileNotFoundException set to break execution when thrown, instead of when 'User-unhandled'.

To enable 'Just My Code', go to Tools >> Options >> Debugging >> General >> Enable Just My Code. To turn off breaking of execution when FileNotFound is thrown, go to Debug >> Exceptions >> Find >> enter 'FileNotFoundException' >> untick the 'Thrown' checkbox from System.IO.FileNotFoundException.

Allon Guralnek
  • 15,813
  • 6
  • 60
  • 93
  • +1 for the update: this explains the different behavior when debugging test cases – mbx Sep 19 '14 at 07:04
  • 3
    Your update suggests that this exception should not occur in .NET 4.5, but I am still seeing it. – Tim Sparkles Feb 20 '15 at 19:44
  • @Timbo: I don't see why you wouldn't get that exception with .NET 4.5. It still looks for a file, and if the file is missing, a `FileNotFoundException` will be thrown. The difference is not in how the assembly's existence is checked, but in how to generate it once it's determined that it's missing. Before, it used textual C# code generation with a call to the C# compiler to create the IL. Starting with .NET 4.5 it emits IL directly, without the use of a compiler. – Allon Guralnek Feb 23 '15 at 13:58
  • Throws filenot found exception twice, first finding the "supposedly generated" assembly from local path and then in GAC and 3rd time works normally. View-able from process-monitor; consumes resources/cpu. – hB0 Jun 12 '15 at 12:22
  • 1
    I just wish MS would implement this as if (File.Exists(...)) { Load } else { Fallback } instead of try { Load } catch { Fallback }. Exception-based flow control smells bad and makes my debugging experience more difficult and brittle than necessary. – Tim Sparkles Jul 28 '15 at 22:19
  • 1
    @Timbo: A simple `File.Exists()` may not be sufficient. Locating an assembly is not a simple affair, the runtime looks in several locations and I believe the behaviour changes according to the environment (console application vs being hosted in IIS, etc). I guess what should have been implemented was a `TryLoadAssembly()` or something similar. – Allon Guralnek Jul 29 '15 at 04:40
  • Excellent point - I thought about assembly resolution last night after I got home and realized File.Exists would be insufficient. Maybe what I really want is a specialized exception type AssemblyNotFoundException so I can ignore that one but still catch 1st-chance FileNotFoundExceptions that actually matter. – Tim Sparkles Jul 29 '15 at 21:57
  • @Timbo: Then simply [generate the serialization assembly at build time](http://stackoverflow.com/a/1155790/149265). – Allon Guralnek Jul 30 '15 at 04:48
72

In Visual Studio project properties ("Build" page, if I recall it right) there is an option saying "generate serialization assembly". Try turning it on for a project that generates [Containing Assembly of MyType].

VladV
  • 10,093
  • 3
  • 32
  • 48
66

There is a workaround for that. If you use

XmlSerializer lizer = XmlSerializer.FromTypes(new[] { typeof(MyType) })[0];

it should avoid that exception. This worked for me.

WARNING: Do not use multiple times, or you will have a memory leak

You will leak memory like crazy if you use this method to create instances of XmlSerializer for the same type more than once!

This is because this method bypasses the built-in caching provided the XmlSerializer(type) and XmlSerializer(type, defaultNameSpace) constructors (all other constructors also bypass the cache).

If you use any method to create an XmlSerializer that is not via these two constructors, you must implement your own caching or you'll hemorrhage memory.

Tom Leys
  • 18,473
  • 7
  • 40
  • 62
quadfinity
  • 877
  • 1
  • 8
  • 9
  • 45
    **WARNING:** You will leak memory like crazy if you use this method to create instances of `XmlSerializer` for the same type more than once! This is because this method bypasses the built-in caching provided the `XmlSerializer(type)` and `XmlSerializer(type, defaultNameSpace)` constructors (all other constructors also bypass the cache). If you use any method to create an `XmlSerializer` that is not via these two constructors, you must implement your own caching or you'll hemorrhage memory. – Allon Guralnek Oct 31 '12 at 18:10
  • 1
    Just stumbled upon this question, but I believe you are incorrect, @AllonGuralnek - `FromTypes` calls `FromMappings` which calls `GetSerializersFromCache` – JerKimball Jan 22 '13 at 21:53
  • @JerKimball: Just test it and you'll see. Try calling `XmlSerializer.FromTypes(new[] { typeof(Stopwatch)})` 10,000 times and you'll see the memory consumption skyrocket. Try running `new XmlSerializer(typeof(Stopwatch))` 10,000 times and not only will it complete instantly, it will use almost no memory. I ran that test before posting my comment. – Allon Guralnek Jan 23 '13 at 14:18
  • 4
    @AllonGuralnek Well I'll be damned...you are absolutely correct; further digging in via Reflector shows that while it does check the cache, it does so **after** generating the serialization assembly! Wtf?!? – JerKimball Jan 25 '13 at 20:02
  • 1
    @AllonGuralnek What's worse, that means this page is outright lying: http://msdn.microsoft.com/en-us/library/ff650685.aspx - jump to "Initializing XmlSerializer by Calling FromTypes on Startup" – JerKimball Jan 25 '13 at 20:09
  • 4
    Turns out its a known bug: http://weblogs.asp.net/cschittko/archive/2005/01/14/353435.aspx – JerKimball Jan 25 '13 at 20:22
  • 3
    @JerKimball: That page isn't actually lying. As you discovered, `FromTypes` does appear to populate the cache. So it should be a valid way to warm up an empty `XmlSerializer` cache in one statement (like the article suggests), but a really bad way to retrieve anything from it (should only be done via the simplest constructors). In any case, I didn't know it was a bug, I always thought anything that leaks is supposed to leak (like the more advanced `XmlSerializer` constructors). I wouldn't have even considered using `FromTypes()` since you can just do `types.Select(t => new XmlSerializer(t))`. – Allon Guralnek Jan 25 '13 at 23:14
  • 2
    @AllonGuralnek The non-probing aspect of using `FromTypes` does have its appeal - even tho the exceptions thrown are all caught, it is a pricely operation; the 'cache your own way' approach appears to be the only workaround, as the only officially supported fix looks to be in an obscure web-based assembly. (edit: frankly, I'm all for porting everything over to data contracts :) ) – JerKimball Jan 25 '13 at 23:39
31

I ran into this exact issue and couldn't get around it by any of the solutions mentioned.

Then I finally found a solution. It appears that the serializer needs not only the type, but the nested types as well. Changing this:

XmlSerializer xmlSerializer = new XmlSerializer(typeof(T));

To this:

XmlSerializer xmlSerializer = new XmlSerializer(typeof(T).GetNestedTypes());

Fixed the issue for me. No more exceptions or anything.

stema
  • 90,351
  • 20
  • 107
  • 135
Frosty
  • 321
  • 3
  • 2
9

My solution is to go straight to reflection to create the serializer. This bypasses the strange file loading that causes the exception. I packaged this in a helper function that also takes care of caching the serializer.

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;
    }
}
edeboursetty
  • 5,669
  • 2
  • 40
  • 67
  • 2 problems here - first your code isn't thread-safe, and second (more importantly) you are attempting to replicate what the .net runtime already does (based on the ctor you are using). i.e. there is no need for this code – Dave Black Jul 28 '15 at 19:42
  • @DaveBlack: Yes, quadfinity's answer with caching to a ConcurrentDictionary would be better – edeboursetty Jul 30 '15 at 13:52
  • @d-b My 2nd point was that caching is not even needed - as long as you are using one of the 2 ctors that the framework caches (OP is using the first). From MSDN: To increase performance, the XML serialization infrastructure dynamically generates assemblies to serialize and deserialize specified types. The framework finds and reuses those assemblies. This behavior occurs only when using the following ctors: XmlSerializer.XmlSerializer(Type) XmlSerializer.XmlSerializer(Type, String) Reference: https://msdn.microsoft.com/en-us/library/system.xml.serialization.xmlserializer(v=vs.110).aspx – Dave Black Jul 30 '15 at 15:16
  • @DaveBlack: Yes, but these constructors throw and catch an exception internally even when the usage is completely valid. This is bad, and this is the reason why the OP asked the question in the first place. – edeboursetty Jul 31 '15 at 08:47
  • @d-b True, but what I meant to say (but wasn't clear - my apologies) was that the only lines of your soln that are necessary are the first 3 lines in the else condition. – Dave Black Jul 31 '15 at 14:54
  • @DaveBlack I have used the 3 lines of code in this else statement and it works, should i use this or should I use a solution like the one provided here? http://stackoverflow.com/questions/134224/generating-an-xml-serialization-assembly-as-part-of-my-build The thing that i like about the code of d--b is that it only requires me to change a small thing in my common.dll where i have de serialize and deserialze method and not have to change all the csproj of all my projects. – Vincent Nov 10 '15 at 08:46
8

To avoid the exception you need to do two things:

  1. Add an attribute to the serialized class (I hope you have access)
  2. Generate the serialization file with sgen.exe

Add the System.Xml.Serialization.XmlSerializerAssembly attribute to your class. Replace 'MyAssembly' with the name of the assembly where MyClass is in.

[Serializable]
[XmlSerializerAssembly("MyAssembly.XmlSerializers")]
public class MyClass
{
…
}

Generate the serialization file using the sgen.exe utility and deploy it with the class’s assembly.

‘sgen.exe MyAssembly.dll’ will generate the file MyAssembly.XmlSerializers.dll

These two changes will cause the .net to directly find the assembly. I checked it and it works on .NET framework 3.5 with Visual Studio 2008

Ami Bar
  • 81
  • 1
  • 2
  • Ok, and did it fail without these changes, and if so, why? – John Saunders Oct 30 '09 at 01:51
  • 1
    I can find no reason for why my project, 4.0 in VS2012, suddenly started failing. "Ignoring" the error was not an option, because it occurred every time I tried to access Active Directory; thus ignoring would mean not authenticating. I am still very frustrated that VS2012 won't auto-generate the serialization DLL properly. However, these steps provided the perfect solution. – sfuqua Apr 02 '13 at 13:10
7

Function XmlSerializer.FromTypes does not throw the exception, but it leaks the memory. Thats why you need to cache such serializer for every type to avoid memory leaking for every instance created.

Create your own XmlSerializer factory and use it simply:

XmlSerializer serializer = XmlSerializerFactoryNoThrow.Create(typeof(MyType));

The factory looks likes:

public static class XmlSerializerFactoryNoThrow
{
    public static Dictionary<Type, XmlSerializer> _cache = new Dictionary<Type, XmlSerializer>();

    private static object SyncRootCache = new object();        

    /// <summary>
    /// //the constructor XmlSerializer.FromTypes does not throw exception, but it is said that it causes memory leaks
    /// http://stackoverflow.com/questions/1127431/xmlserializer-giving-filenotfoundexception-at-constructor
    /// That is why I use dictionary to cache the serializers my self.
    /// </summary>
    public static XmlSerializer Create(Type type)
    {
        XmlSerializer serializer;

        lock (SyncRootCache)
        {
            if (_cache.TryGetValue(type, out serializer))
                return serializer;
        }

        lock (type) //multiple variable of type of one type is same instance
        {
            //constructor XmlSerializer.FromTypes does not throw the first chance exception           
            serializer = XmlSerializer.FromTypes(new[] { type })[0];
            //serializer = XmlSerializerFactoryNoThrow.Create(type);
        }

        lock (SyncRootCache)
        {
            _cache[type] = serializer;
        }
        return serializer;
    }       
}

More complicated version without possibility of memory leak (please someone review the code):

    public static XmlSerializer Create(Type type)
    {
        XmlSerializer serializer;

        lock (SyncRootCache)
        {
            if (_cache.TryGetValue(type, out serializer))
                return serializer;
        }

        lock (type) //multiple variable of type of one type is same instance
        {
            lock (SyncRootCache)
            {
                if (_cache.TryGetValue(type, out serializer))
                    return serializer;
            }
            serializer = XmlSerializer.FromTypes(new[] { type })[0];
            lock (SyncRootCache)
            {
                _cache[type] = serializer;
            }
        }          
        return serializer;
    }       
}
Tomas Kubes
  • 23,880
  • 18
  • 111
  • 148
  • You should use ConcurrentDictionary instead. This code can deadlock. – Behrooz Nov 21 '17 at 12:43
  • How can it deadlock if all management with dictionary is in lock section? – Tomas Kubes Nov 21 '17 at 17:02
  • 1
    Sorry, I got the words confused. What I meant is that it can Insert an item more than once. because there is a gap between when it checks for existance and when it inserts. concurrent dictionary uses some kind of two-phase locking (bag[0] and then bag[hash]]) and keeps a reference to the bag that must insert/contain the item you're working. It's faster, safer and cleaner. – Behrooz Nov 23 '17 at 12:57
  • 1
    Yes and no. You are right that it can happen that in the same time one serializer of same type will be created on two threads in parallel and then added to dictionary twice. In such case second insert will just replace the first one, but the lock section guarantee thread safety and the overall disadvantage is small memory leak. This is performance optimization, because you don't want thread one with Serializer of type A wait be blocked by thread two with serializer of type B in real scenario. – Tomas Kubes Nov 23 '17 at 15:32
  • I can imagine the solution might be even better (without theoretical memory leak), but more complicated. – Tomas Kubes Nov 23 '17 at 15:34
  • 1
    @Behrooz Please check the new version of source code. – Tomas Kubes Nov 23 '17 at 15:39
  • 1
    The 2nd version looks good to me. btw, you can use _cache itself for locking. – Behrooz Nov 24 '17 at 22:52
6

This exception can also be trapped by a managed debugging assistant (MDA) called BindingFailure.

This MDA is useful if your application is designed to ship with pre-build serialization assemblies. We do this to increase performance for our application. It allows us to make sure that the pre-built serialization assemblies are being properly built by our build process, and loaded by the application without being re-built on the fly.

It's really not useful except in this scenario, because as other posters have said, when a binding error is trapped by the Serializer constructor, the serialization assembly is re-built at runtime. So you can usually turn it off.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
HiredMind
  • 1,827
  • 17
  • 27
2

In Visual Studio project properties there is an option saying "generate serialization assembly". Try turning it on for a project that generates [Containing Assembly of MyType].

Pascal
  • 21
  • 1
2

Just as reference. Taking from D-B answer and comments, I came with this solution which is close to D-B solution. It works fine in all of my cases and it is thread safe. I don't think that using a ConcurrentDictionary would have been ok.

using System;
using System.Collections.Generic;
using System.Xml.Serialization;

namespace HQ.Util.General
{
    public class XmlSerializerHelper
    {
        private static readonly Dictionary<Type, XmlSerializer> _dictTypeToSerializer = new Dictionary<Type, XmlSerializer>();

        public static XmlSerializer GetSerializer(Type type)
        {
            lock (_dictTypeToSerializer)
            {
                XmlSerializer serializer;
                if (! _dictTypeToSerializer.TryGetValue(type, out serializer))
                {
                    var importer = new XmlReflectionImporter();
                    var mapping = importer.ImportTypeMapping(type, null, null);
                    serializer = new XmlSerializer(mapping);
                    return _dictTypeToSerializer[type] = serializer;
                }

                return serializer;
            }
        }
    }
}

Usage:

        if (File.Exists(Path))
        {
            using (XmlTextReader reader = new XmlTextReader(Path))
            {
                // XmlSerializer x  = new XmlSerializer(typeof(T));
                var x = XmlSerializerHelper.GetSerializer(typeof(T));

                try
                {
                    options = (OptionsBase<T>)x.Deserialize(reader);
                }
                catch (Exception ex)
                {
                    Log.Instance.AddEntry(LogType.LogException, "Unable to open Options file: " + Path, ex);
                }
            }
        }
Eric Ouellet
  • 10,996
  • 11
  • 84
  • 119
1

A custom class to serialise:

[Serializable]
public class TestClass
{
    int x = 2;
    int y = 4;
    public TestClass(){}
    public TestClass(int x, int y)
    {
        this.x = x;
        this.y = y;
    }

    public int TestFunction()
    {
        return x + y;
    }
}

I have attached the code snippet. Maybe this can help you out.

static void Main(string[] args)
{
    XmlSerializer xmlSerializer = new XmlSerializer(typeof(TestClass));

    MemoryStream memoryStream = new MemoryStream();
    XmlTextWriter xmlWriter = new XmlTextWriter(memoryStream, Encoding.UTF8);

    TestClass domain = new TestClass(10, 3);
    xmlSerializer.Serialize(xmlWriter, domain);
    memoryStream = (MemoryStream)xmlWriter.BaseStream;
    string xmlSerializedString = ConvertByteArray2Str(memoryStream.ToArray());

    TestClass xmlDomain = (TestClass)DeserializeObject(xmlSerializedString);

    Console.WriteLine(xmlDomain.TestFunction().ToString());
    Console.ReadLine();
}
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
shahjapan
  • 13,637
  • 22
  • 74
  • 104
1

I was having a similar problem, and ignoring the exception did not work for me. My code was calling NServiceBus' configuration Configure.With(...).XmlSerializer()...

What fixed it for me was to change the platform for my project.

  1. Go to Build\Configuration Manager...
  2. Find your project and change Platform (in my case from x86 to Any CPU)
kkelley
  • 11
  • 1
1

Seen a lot of recommendations to use a ConcurrentDictionary, but no solid examples of it, so I'm going to throw my hat into this solution race. I'm not a thread-safe developer, so if this code isn't solid, please speak up for the sake of those who follow after.

public static class XmlSerializerHelper
{
    private static readonly ConcurrentDictionary<Type, XmlSerializer> TypeSerializers = new ConcurrentDictionary<Type, XmlSerializer>();

    public static XmlSerializer GetSerializer(Type type)
    {
        return TypeSerializers.GetOrAdd(type,
        t =>
        {
            var importer = new XmlReflectionImporter();
            var mapping = importer.ImportTypeMapping(t, null, null);
            return new XmlSerializer(mapping);
        });
    }
}

I've seen other posts involving ConcurrentDictionary and Lazy loading the value. I'm not sure if that's relevant here or not, but here's the code for that:

private static readonly ConcurrentDictionary<Type, Lazy<XmlSerializer>> TypeSerializers = new ConcurrentDictionary<Type, Lazy<XmlSerializer>>();

public static XmlSerializer GetSerializer(Type type)
{
    return TypeSerializers.GetOrAdd(type,
    t =>
    {
        var importer = new XmlReflectionImporter();
        var mapping = importer.ImportTypeMapping(t, null, null);
        var lazyResult = new Lazy<XmlSerializer>(() => new XmlSerializer(mapping), LazyThreadSafetyMode.ExecutionAndPublication);
        return lazyResult;
    }).Value;
}
Airn5475
  • 2,452
  • 29
  • 51
1

This exception is a part of the XmlSerializer's normal operation. It is expected and will be caught and handled inside of the Framework code.

To see only exceptions that are thrown in your own code (and those that "bubble up" to your code because they are not caught by the library that throws them), use "Enable Just My Code":

enter image description here

(The accepted answer ignores the FileNotFoundException, but that is a bad practice.)

SymboLinker
  • 884
  • 6
  • 15
0

Your type may reference other assemblies which cannot be found neither in the GAC nor in your local bin folder ==> ...

"or one of its dependencies. The system cannot find the file specified"

Can you give an example of the type you want to serialize?

Note: Ensure that your type implements Serializable.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Henrik
  • 568
  • 4
  • 10
0

I had the same problem until I used a 3rd Party tool to generate the Class from the XSD and it worked! I discovered that the tool was adding some extra code at the top of my class. When I added this same code to the top of my original class it worked. Here's what I added...

#pragma warning disable
namespace MyNamespace
{
  using System;
  using System.Diagnostics;
  using System.Xml.Serialization;
  using System.Collections;
  using System.Xml.Schema;
  using System.ComponentModel;
  using System.Xml;
  using System.Collections.Generic;

  [System.CodeDom.Compiler.GeneratedCodeAttribute("System.Xml", "4.6.1064.2")]
  [System.SerializableAttribute()]
  [System.Diagnostics.DebuggerStepThroughAttribute()]
  [System.ComponentModel.DesignerCategoryAttribute("code")]
  [System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true)]
  [System.Xml.Serialization.XmlRootAttribute(Namespace = "", IsNullable = false)]
  public partial class MyClassName
  {
  ...
TheJonz
  • 394
  • 2
  • 11
0

Had a similar problem in one of my .Net Standard dlls.

I used Microsoft.XmlSerializer.Generator nuget, which pre-generating XmlSerializer on .Net Core and .Net Standard.

R.G
  • 27
  • 4
0

Initial answer from Martin Sheburn is correct. Code samples from edeboursetty, tomas-kubes), quadfinity should solve the problem of not raising excess exceptions in debugger.

Here is a shorter solution, however:

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]);
    }
}
egors
  • 55
  • 5
0

I had this problem in vb.net when trying to save My.Settings. The setting in question is of type Specialized.StringCollection.

The exception occurred on the call to My.Settings.Save. When I tried to read the settings after restarting the program, the settings were empty (variable showed up in debugger as Nothing).

In fact, it seems that the settings were being saved, but that they were failing to load. The solution for me was simply to set some initial values in the Settings page of Visual Studio. The settings that I thought had previously failed to be saved then loaded OK (not the initial values I had just entered). The exception still occurs but when retrieving the setting, rather than saving.

0

I was getting the same error, and it was due to the type I was trying to deserialize not having a default parameterless constructor. I added a constructor, and it started working.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
kay.one
  • 7,622
  • 6
  • 55
  • 74