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?
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.
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.
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:
The factory looks likes:
More complicated version without possibility of memory leak (please someone review the code):
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.
Your type may reference other assemblies which cannot be found neither in the GAC nor in your local bin folder ==> ...
Can you give an example of the type you want to serialize?
Note: Ensure that your type implements Serializable.
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:
To this:
Fixed the issue for me. No more exceptions or anything.
To avoid the exception you need to do two things:
Add the System.Xml.Serialization.XmlSerializerAssembly attribute to your class. Replace 'MyAssembly' with the name of the assembly where MyClass is in.
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