Scott Hanselman

Changing where XmlSerializer Outputs Temporary Assemblies

September 17, 2007 Comment on this post [9] Posted in ASP.NET | Learning .NET | XML | XmlSerializer
Sponsored By

With this tip, I couldn't find any documentation, so you're on your own. That means no help/support from me or anywhere. YMMV - Your Mileage May Vary. No warranties. Enjoy.

Someone asked:

"When using the XmlSerializer from ASP.NET there are permissions issues can can be solved by granting the user account read/write permissions on the %SYSTEMROOT%\Temp folder but I would much rather have the temporary files created in a different folder"

So I poked around. If you want the XmlSerializer to output it's assemblies elsewhere, here's how. Note that I used the previous tip on How To Debug into a .NET XmlSeraizlizer Generated Assembly just to prove this was working. It's not needed for this tip!

To start, let's see where the temporary files end up usually.

First, I'll add this to my web.config (or whatever.exe.config if you like). This is just to visualize and confirm. It's not needed for this tip.

         <add name="XmlSerialization.Compilation" value="1" />

I'll debug my application, but I'll use SysInternal's Process Monitor and set the filter to only show processes whose name contains the string "WebDev" and see what files the VS WebDev Server writes to. If you're using IIS, you would search for W3WP or ASPNET_WP.

Process Monitor - Sysinternals

Here I can see it writing to C:\Users\Scott\AppData\Local\Temp. The file names are auto-generated...note their names, in my case 6txrbdy.0.*. To prove these are the real generated XmlSerializers, I'll put a breakpoint on my app just before I call CreateSerializer and then drag the .cs file over from the TEMP folder into VS.NET. Note that the .PDB will get loaded when I hit F11 to step into.

XmlSerializerAlternateLocation (Debugging) - Microsoft Visual Studio (Administrator) (2)

Make note of the Call Stack. See the name of the assembly and the name of the .cs file? So, we're sure now where this XmlSerializer came from; it came from C:\Users\Scott\AppData\Local\Temp. If we were running IIS, it'd have been in %SYSTEMROOT%\Temp. The point being, it's automatic and it's temporary and your process needs WRITE access to that folder.

Now, poking around in Reflector with the not-used-often-enough Analyze method shows that XmlSerializerFactory.CreateSerializer eventually ends up in XmlSerializerCompilerParameters.Create which looks for a Configuration Section called “xmlSerializer” and a key called TempFilesLocation.

Lutz Roeders .NET Reflector (3)

That actually means it's looking for a section called System.Xml.Serializer and an element called xmlSerializer and an attribute called tempFilesLocation.

I'll add this to my web.config now:

  <xmlSerializer tempFilesLocation="c:\\foo"/> 

...and create a c:\\foo directory. Make sure your hosting process has write access to the directory.

I'll run my app again, and check out that new folder.

Administrator CWindowssystem32cmd.exe (2)

I've got newly generated XmlSerializer temporary assemblies in there. Undocumented, yes, but it does the job. Note, stuff like this can totally go away at any minute, so don't base your whole design on things like this. It's your tush, not mine, on the line.

About Scott

Scott Hanselman is a former professor, former Chief Architect in finance, now speaker, consultant, father, diabetic, and Microsoft employee. He is a failed stand-up comic, a cornrower, and a book author.

facebook twitter subscribe
About   Newsletter
Hosting By
Hosted in an Azure App Service
September 17, 2007 4:44
So does this mean when you're fully settled in your new position you'll have the power to get someone to document such a hack? Err...undocumented best practice? ;)

September 17, 2007 9:17
I'm certainly settled in enough to get into trouble!
September 17, 2007 21:21
I think it would make more sense to push for having that changed from an undocumented hack to a documented feature (with forward-compatibility assumed).
September 18, 2007 0:08
Or better yet, change the default into something much more reasonable, such as the user's temp folder (%TEMP%).
September 20, 2007 12:30
Great post Scott.

A couple of comments though:
1/ you'll get this working with version 2.0.50727.821 or later of system.xml.dll
2/ Microsoft KB#934529 somehow makes "tempFilesLocation" a documented attribute

BTW, any clue as how those temp files get cleaned up?
September 26, 2007 12:30
You helped me a lot!
One question - a little bit off topic: is there any list of all switches available? I'd like to have a list of all the names (like 'XmlSerialization.Compilation') used by .NET framework.
October 30, 2007 16:29
All our ASP.NET apps run as a domain user in our production environment. We have a do-nothing service that also runs on each web server as the same domain user, this forces the domain user's profile to be loaded and therefore a user %TEMP% environment variable is used instead of the system %TEMP% variable.

This issue can be a real PITA with SharePoint as Impersonation is configured for WSS so the calling user's identity is used to access %TEMP% (which can be quite annoying trying to create no-code workflows using SharePoint designer).
November 14, 2007 15:29
Scott, great tip, but any idea why the problem of some XmlSerializer constructors not using the cache wasn't fixed in 3.0? And any idea what the status is in 3.5? Seems strange such a widely known problem keeps persisting through releases.
November 15, 2007 1:11
I can't speak for the team, but "fixing" that would be a serious contractual change since folks count on that internal behavior. The issue was only for the constructors with the most parameters...Have you used the MVP.XML library that includes a smarter XmlSerializerFactory and fixes this issue?

Comments are closed.

Disclaimer: The opinions expressed herein are my own personal opinions and do not represent my employer's view in any way.