Changing where XmlSerializer Outputs Temporary Assemblies
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.
"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.
<configuration> <system.diagnostics> <switches> <add name="XmlSerialization.Compilation" value="1" /> </switches> </system.diagnostics> </configuration>
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.
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.
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.
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:
<system.xml.serialization> <xmlSerializer tempFilesLocation="c:\\foo"/> </system.xml.serialization>
...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.
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.
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.
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?
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.
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).
Comments are closed.