This code produces a FileNotFoundException, but ultimately runs without issue:
void ReadXml()
{
XmlSerializer serializer = new XmlSerializer(typeof(MyClass));
//...
}
Here is the exception:
A first chance exception of type 'System.IO.FileNotFoundException' occurred in mscorlib.dll
Additional information: Could not load file or assembly 'MyAssembly.XmlSerializers, Version=1.4.3190.15950, Culture=neutral, PublicKeyToken=null' or one of its dependencies. The system cannot find the file specified.
It appears that the framework automatically generates the serialization assembly if it isn't found. I can generate it manually using sgen.exe, which alleviates the exception.
How do I get visual studio to generate the XML Serialization assembly automatically?
Update: The Generate Serialization Assembly: On setting doesn't appear to do anything.
This is how I managed to do it by modifying the MSBUILD script in my .CSPROJ file:
First, open your .CSPROJ file as a file rather than as a project. Scroll to the bottom of the file until you find this commented out code, just before the close of the Project tag:
<!-- To modify your build process, add your task inside one of the targets below and uncomment it. Other similar extension points exist, see Microsoft.Common.targets.
<Target Name="BeforeBuild">
</Target>
<Target Name="AfterBuild">
</Target>
-->
Now we just insert our own AfterBuild target to delete any existing XmlSerializer and SGen our own, like so:
<Target Name="AfterBuild" DependsOnTargets="AssignTargetPaths;Compile;ResolveKeySource" Inputs="$(MSBuildAllProjects);@(IntermediateAssembly)" Outputs="$(OutputPath)$(_SGenDllName)">
<!-- Delete the file because I can't figure out how to force the SGen task. -->
<Delete
Files="$(TargetDir)$(TargetName).XmlSerializers.dll"
ContinueOnError="true" />
<SGen
BuildAssemblyName="$(TargetFileName)"
BuildAssemblyPath="$(OutputPath)"
References="@(ReferencePath)"
ShouldGenerateSerializer="true"
UseProxyTypes="false"
KeyContainer="$(KeyContainerName)"
KeyFile="$(KeyOriginatorFile)"
DelaySign="$(DelaySign)"
ToolPath="$(TargetFrameworkSDKToolsDirectory)"
Platform="$(Platform)">
<Output
TaskParameter="SerializationAssembly"
ItemName="SerializationAssembly" />
</SGen>
</Target>
That works for me.