FileNotFoundException when Deserializing XML
Asked Answered
B

3

10

We've recently starting seeing FileNotFoundException's being thrown sporadically while deserializing XML. The message is that the temporary assembly used to map from the XML to code can't be found. From this document it looks like this can happen when this file can't be created by the .NET Framework (however the reason why is not captured even in the inner exception).

Here is the exception:

Type : System.IO.FileNotFoundException, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
Message : Could not find file 'C:\Documents and Settings\user\Local Settings\Temp\c5_nfoko.dll'.

The file name differs on every error, but the error is always the same, it originates from here (full callstack at bottom):

at System.Xml.Serialization.XmlSerializer.GenerateTempAssembly(XmlMapping xmlMapping, Type type, String defaultNamespace)
at System.Xml.Serialization.XmlSerializer..ctor(Type type, String defaultNamespace)
at System.Xml.Serialization.XmlSerializer..ctor(Type type)

When the CSharpCodeGenerator attempts to generate the assembly. We've been using this code in production for years and it has been very stable. It just started failing in the last week or so. We've wondered if it could have anything to do with the latest Microsoft security patch as it affects version of our code in .NET 2.0 and .NET 4.0 on multiple operating systems (XP and Server 2003).

The error is sporadic and running the process again usually causes it to go away. This is a single threaded command line application that retrieves files and inserts them into a database.

I haven't been able to find anyone else with the same issue, but it isn't isolated to the same line of code, we have a couple of places that use the System.Xml.Serialization code and we've seen this error from each. This code also isn't something that we've changed recently.

The closest other post I can find is this one.

On our QA VM there is no virus scanner so I don't think it is an issue with that. We've also seen this issue in both our hosted environment and in a separate client site.

We have tried:

  1. Cleaning up this temp directory
  2. Checking permissions on the temp directory (user is local admin on box)
  3. Generating XmlSerializers.dll's by using sgen.exe and deploying them to the app folder (the problem persists as if the .NET Framework doesn't want to use these assemblies).

If anyone has any ideas or suggestions that would be helpful.

Full callstack:

Type : System.IO.FileNotFoundException, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
Message : Could not find file 'C:\Documents and Settings\user\Local Settings\Temp\c5_nfoko.dll'.
Source : mscorlib
Help link : 
FileName : C:\Documents and Settings\user\Local Settings\Temp\c5_nfoko.dll
FusionLog : 
Data : System.Collections.ListDictionaryInternal
TargetSite : Void WinIOError(Int32, System.String)
Stack Trace :    at System.IO.__Error.WinIOError(Int32 errorCode, String maybeFullPath)
at System.IO.FileStream.Init(String path, FileMode mode, FileAccess access, Int32 rights, Boolean useRights, FileShare share, Int32 bufferSize, FileOptions options, SECURITY_ATTRIBUTES secAttrs, String msgPath, Boolean bFromProxy)
at System.IO.FileStream..ctor(String path, FileMode mode, FileAccess access, FileShare share)
at Microsoft.CSharp.CSharpCodeGenerator.FromFileBatch(CompilerParameters options, String[] fileNames)
at Microsoft.CSharp.CSharpCodeGenerator.FromSourceBatch(CompilerParameters options, String[] sources)
at Microsoft.CSharp.CSharpCodeGenerator.System.CodeDom.Compiler.ICodeCompiler.CompileAssemblyFromSourceBatch(CompilerParameters options, String[] sources)
at System.CodeDom.Compiler.CodeDomProvider.CompileAssemblyFromSource(CompilerParameters options, String[] sources)
at System.Xml.Serialization.Compiler.Compile(Assembly parent, String ns, XmlSerializerCompilerParameters xmlParameters, Evidence evidence)
at System.Xml.Serialization.TempAssembly.GenerateAssembly(XmlMapping[] xmlMappings, Type[] types, String defaultNamespace, Evidence evidence, XmlSerializerCompilerParameters parameters, Assembly assembly, Hashtable assemblies)
at System.Xml.Serialization.TempAssembly..ctor(XmlMapping[] xmlMappings, Type[] types, String defaultNamespace, String location, Evidence evidence)
at System.Xml.Serialization.XmlSerializer.GenerateTempAssembly(XmlMapping xmlMapping, Type type, String defaultNamespace)
at System.Xml.Serialization.XmlSerializer..ctor(Type type, String defaultNamespace)
at System.Xml.Serialization.XmlSerializer..ctor(Type type)
Balkanize answered 6/1, 2012 at 21:27 Comment(9)
Does it affect a .Net 2.0 app reading a .Net 4.0 serialized file?Garrard
can you find that .dll if you do a windows search..? and if so can that be GAC'd or have the copylocal property set true in the project(s) not sure how you are referencing it currently.. GAC for 2.0 and 4.0 are not shared they have their own separate GAC FYIMuzzle
Does this happen, when the VM is IO-bound? If yes, I have seen this before: No cure, but a workaround - force a flush of some file on this disk and wait 1ms.Rigel
We wouldn't be able to find that .dll ... the error is a bit of a misnomer. The problem is that for some reason the .NET base class library can't compile the temp .cs file it has created into a temp .dllBalkanize
You said that "3. Generating XmlSerializers.dll's by using sgen.exe and deploying them to the app folder (the problem persists as if the .NET Framework doesn't want to use these assemblies)." - are you letting the framework pick the assembly by itself or referencing it directly in your code?Phyllous
I'm not referencing the XmlSerializers.dll anywhere (letting the framework pick the assembly). The project with the data object (serialized) and the project that is doing the serialization (serializer) are two different projects. Should I be referencing the XmlSerializers.dll file in either of these projects?Balkanize
I think, this posting describes the problem: #1127931Interrelate
Actually that post and the info from Carlos helped me piece together something that seems to be working. By referencing the XmlSerializerAssemblyAttribute in the class being deserialized it seems to for it to use my XmlSerializers.dll assembly. I'll want to do a bit more testing around this but we were able to reproduce the other error fairly reliably and I haven't seen it since deploying new code (dll's) with this attribute.Balkanize
Here is a link to the specific post that helped me: https://mcmap.net/q/86561/-xmlserializer-giving-filenotfoundexception-at-constructorBalkanize
R
1

I had almost the same problem with ASP.NET. The reason is that temp DLLs written in that folder are remembered somewhere, maybe in references from other temp DLL.

The solution is to delete all files in the C:\Documents and Settings\user\Local Settings\Temp folder. Some of them are likely to be locked and you need to delete files in a few iterations because locked files are most likely the source of a problem (from my experience). When temp folder is clear, all works as intended again (at least for me).

Raama answered 10/1, 2012 at 14:29 Comment(1)
We tried cleaning up the temp folder, but we still had the same issue. The problem appears to be a failure of csc.exe to turn the temp .cs files into assemblies at run time, however this is sporadic.Balkanize
R
0

Microsoft's XML serializer is very bad in its own right. The exception that you are getting is because .NET generates the assembly on the fly every time you create a new XML serializer. To prevent this as much as possible, implement a dictionary with key of the type you trying to serialize and the XML serializer as value. This sort of caching will allow you to encounter this first chance exception only the first time you are serializing an unknown type.

Have a look at Microsoft's MSDN website, XmlSerializer Class. There is a paragraph which tells you what I just said.

Rambler answered 14/2, 2012 at 8:40 Comment(0)
D
0

I ran on this problem recently when running a process as a system service (on SYSTEM user). In my case the problem was the C:\Windows\TEMP had a read-only attribute. Clearing this attribute solved the problem.

Dixon answered 1/9, 2020 at 8:11 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.