I inherited an old ASP.NET 2.0 web application that included a serializable “Configuration” project. .NET generates temporary XMLSerializers.dll assemblies for serializable classes, i.e. Configuration.XMLSerializers.dll in this case. Serializing a class allows it to be transported or persisted with state in the form of XML. The application has been running in IIS 6.0 on Server 2003 R2 for a couple years without any issues. Migrating it to Server 2008 R2 and IIS 7.0 without modification didn’t fair as well as the w3wp.exe process crashed unceremoniously on each startup. After accounting for all the ususal suspects, rebuilding with Platform x86, disabling DEBUG and TRACE constants in the project, setting the Application Pool to 32-bit, ASP.NET 2.0 and Classic mode in IIS 7 didn’t resolve the issue either. Microsoft’s Debug Diagnostics utility can be helpful in analyzing IIS process crashes such as my crashing worker process but it only attaches to IIS in 32 bit mode so its not very helpful with IIS 7 x64. My next step was to install the .NET Framwork SDK and run Fusion Log Viewer (fuslogvw.exe) to check for assembly binding errors and there it was, File Not Found error after checking the normal locations for Configuration.XMLSerializers.dll. For some reason IIS 7 wasn’t generating the temporary assembly automatically so I switched back to the project and set the Generate serialization assembly property on the project Build options from the default “Auto” to “On” and rebuilt, still no XMLSerializers assembly.
Still no luck, why? Visual Studio runs the sgen.exe utility with the /proxytypes switch which tells sgen to only generate serialization assemblies for XML web service proxy types. What!
To force Visual Studio to generate the XMLSerializers assembly on build you can add an AfterBuild target in the project file. For example, open the .csproj file and near the bottom of the file you’ll find a BeforeBuild and AferBuild target section. Modify the project file to include the following SGen task specifically setting the ShouldGenerateSerializer to true and UseProxyTypes to false.
<Target Name=”GenerateSerializationAssembliesForAllTypes” DependsOnTargets=”AssignTargetPaths;Compile;ResolveKeySource” Inputs=”$(MSBuildAllProjects);@(IntermediateAssembly)” Outputs=”$(OutputPath)$(_SGenDllName)”> <SGen BuildAssemblyName=”$(TargetFileName)” BuildAssemblyPath=”$(OutputPath)” References=”@(ReferencePath)” ShouldGenerateSerializer=”true” UseProxyTypes=”false” KeyContainer=”$(KeyContainerName)” KeyFile=”$(KeyOriginatorFile)” DelaySign=”$(DelaySign)” ToolPath=”$(SGenToolPath)”> <Output TaskParameter=”SerializationAssembly” ItemName=”SerializationAssembly” /> </SGen> </Target> <Target Name=”AfterBuild” DependsOnTargets=”GenerateSerializationAssembliesForAllTypes”> </Target>
Reload the project in Visual Studio and rebuild to add the *.XMLSerializers.dll to the project output. Redeploying the updated solution to the IIS 7 server resolved the issue and got the web application up and running.