Xmlserializer Giving Filenotfoundexception at Constructor

XmlSerializer giving FileNotFoundException at constructor

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).

Why does XmlSerializer NOT cause FileNotFoundException in Visual Studio 2019?

Bah. It was that "Just My Code" was checked.

I was thinking I had that unchecked, but I was wrong...sorry to all...

Hangs head in shame :(

First chance exception happened in the constructor of XMLSerializer

First chance means the program hasn't been able to deal with it yet, the debugger comes first. When you let it through, the app will deal with it nicely, so you don't get errors.

In this particular case, the thing is that XMLSerializer can use assemblies with compiled schema information in them. So it tries to load the assembly just in case it exists. If not, it's not a problem, but if it does, it will use that and it will be faster. When you compile your project in release mode, you often get XMLSerializer assemblies.

You should set up Visual Studio to ignore thrown (1st chance) exceptions, and only break on unhandled ones.

FileNotFound exception when using XmlSerializer

If you build with Visual Studio, there is an interesting option for you in the project properties.
On the Build-tab you chan choose to Generate Serialization Assemby (Yes, No, Auto).
If I remember correctly, I did not succeed in generating this assembly with 'Yes' to get rid of that exception. But once I had the impression that setting the option to 'No' led the build to not try searching for such an assembly, so there was no frustrated FileNotFound-Exception anymore.
Anyway, as you already said, the exception is more a cosmetical problem. You could think about suppressing it (configure via Debug/Exceptions... in Visual Studio), at least for the case that it is handled.

edit: The option is only evaluated under certain circumstances, for a final solution see this question (and its answers)

FileNotFoundException in ApplicationSettingsBase

Just an explanation for why this exception is thrown. You can repro the exception with this sample Windows Forms app. Start by adding a setting named "Setting" of type StringCollection. Click the dots in the Value column and enter a couple of strings. Make the form class code look like this:

public partial class Form1 : Form {
public Form1() {
InitializeComponent();
}
protected override void OnFormClosing(FormClosingEventArgs e) {
Properties.Settings.Default.Setting[0] = DateTime.Now.ToString();
Properties.Settings.Default.Save();
base.OnFormClosing(e);
}
}

Debug + Exceptions, tick the Thrown checkbox for CLR exceptions. Run the form and close it, the debugger will stop when the exception is thrown. The top of the call stack looks like this:

mscorlib.dll!System.Reflection.Assembly.nLoad(System.Reflection.AssemblyName fileName, string codeBase, System.Security.Policy.Evidence assemblySecurity, System.Reflection.Assembly locationHint, ref System.Threading.StackCrawlMark stackMark, bool throwOnFileNotFound, bool forIntrospection) + 0x2c bytes 
mscorlib.dll!System.Reflection.Assembly.InternalLoad(System.Reflection.AssemblyName assemblyRef, System.Security.Policy.Evidence assemblySecurity, ref System.Threading.StackCrawlMark stackMark, bool forIntrospection) + 0x80 bytes
mscorlib.dll!System.Reflection.Assembly.Load(System.Reflection.AssemblyName assemblyRef) + 0x1d bytes
System.Xml.dll!System.Xml.Serialization.TempAssembly.LoadGeneratedAssembly(System.Type type = {Name = "StringCollection" FullName = "System.Collections.Specialized.StringCollection"}, string defaultNamespace = null, out System.Xml.Serialization.XmlSerializerImplementation contract = null) + 0xcd bytes
System.Xml.dll!System.Xml.Serialization.XmlSerializer.XmlSerializer(System.Type type = {Name = "StringCollection" FullName = "System.Collections.Specialized.StringCollection"}, string defaultNamespace = null) + 0x105 bytes

You can see the XmlSerializer class hunting for an assembly that contains the XML serializer for the StringCollection class. The LoadGeneratedAssembly method looks like this with the boring bits removed:

internal static Assembly LoadGeneratedAssembly(Type type, string defaultNamespace, out XmlSerializerImplementation contract)
{
...
AssemblyName parent = GetName(type.Assembly, true);
partialName = Compiler.GetTempAssemblyName(parent, defaultNamespace);
parent.Name = partialName;
parent.CodeBase = null;
parent.CultureInfo = CultureInfo.InvariantCulture;
try
{
serializer = Assembly.Load(parent); // <=== here
}
catch (Exception exception)
{
...
}
....
}

And Compiler.GetTempAssemblyName():

internal static string GetTempAssemblyName(AssemblyName parent, string ns)
{
return (parent.Name + ".XmlSerializers" + (((ns == null) || (ns.Length == 0)) ? "" : ("." + ns.GetHashCode())));
}

This GetTempAssemblyName is the evil-doer in this case. The StringCollection class lives in the System.dll assembly, the method generates the name "System.XmlSerializers". This method is designed to find the assembly for your own classes, the one generated by Sgen.exe. Like WindowsApplication1.XmlSerializers.dll for your sample program. But StringCollection is a class in the .NET Framework, the assembly name it generates just isn't valid. There isn't actually a "System.XmlSerializers.dll" assembly in the framework.

Feedback reports about this behavior at connect.microsoft.com have all been closed with "By Design". It was, the original designers considered the cost of preventing the exception too high and decided to just catch the exception. Which all works fine, the exception is indeed caught. You just happen to see it because you got the Thrown checkbox turned on in the Debug + Exceptions dialog.

Making the Xml serialization code behave differently here is not an option. It would have been easy enough for them to simply filter out types in the System.dll assembly, but that's a potentially never-ending battle, there are a lot more assemblies in the framework. A workaround is to use your own class to store the setting instead of using a StringCollection.

XmlSerializer constructor error with class derived from a base class

If you change the XmlTextAttribute to XmlAttribute or XmlElement it should be ok. Since you were trying to use the XmlTextAttribute, it assumed it would be some sort of string. If you want an actual byte array serialized, try the XmlAttribute or XmlElement



Related Topics



Leave a reply



Submit