views:

8538

answers:

5

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.

+1  A: 

Look in the properties on the solution. On the build tab at the bottom there is a dropdown called "Generate Serialization assembly"

Darren Kopp
This does not appear to be producing anything.
Adam Tegen
you have to toggle it to "On". Auto doesn't seem to do anything
Darren Kopp
doesn't produce anything even when set to ON
gnomixa
+15  A: 

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="$(SGenToolPath)">
      <Output TaskParameter="SerializationAssembly" ItemName="SerializationAssembly" />
   </SGen>
</Target>

That works for me.

flipdoubt
Thanks, worked nicely. It helped that I put the classes I needed to serialize into a separate project so that SGEN would just work on those.
Craig Shearer
+6  A: 

The other answers to this question have already mentioned the Project Properties->Build->Generate Serialization Assemblies setting but by default this will only generate the assembly if there are "XML Web service proxy types" in the project.

The best way to understand the exact behaviour of Visual Studio is to to examine the GenerateSerializationAssemblies target within the C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727**Microsoft.Common.targets** file.

You can check the result of this build task from the Visual Studio Output window and select Build from the Show output from: drop down box. You should see something along the lines of

C:\Program Files\Microsoft Visual Studio 8\SDK\v2.0\bin\sgen.exe /assembly:D:\Temp\LibraryA\obj\Debug\LibraryA.dll /proxytypes /reference:.. /compiler:/delaysign- LibraryA -> D:\Temp\LibraryA\bin\Debug\LibraryA.dll

The key point here is the /proxytypes switch. You can read about the various switches for the XML Serializer Generator Tool (Sgen.exe)

If you are familiar with MSBuild you could customise the GenerateSerializationAssemblies target so that SGen task has an attribute of UseProxyTypes="false" instead of true but then you need to take on board all of the associated responsibility of customising the Visual Studio / MSBuild system. Alternatively you could just extend your build process to call SGen manually without the /proxytypes switch.

If you read the documentation for SGen they are fairly clear that Microsoft wanted to limit the use of this facility. Given the amount of noise on this topic, it's pretty clear that Microsoft did not do a great job with documenting the Visual Studio experience. There is even a Connect Feedback item for this issue and the response is not great.

Martin Hollingsworth
A: 

Changing Generate Serialization Assembly to ON - Works. Just Curiously, I ran into this trouble, when i cleaned my Solution & Rebuild it. I have 4 Projects in my Solution. Any one care to throw some light on why would this happen.

Arun Dev
+1  A: 

In case someone else runs into this problem suddenly after everything was working fine before: For me it had to do with the "Enable Just My Code (Managed Only)" checkbox being unchecked in the options menu (Options -> Debugging) (which was automatically switched off after installing .NET Reflector).

EDIT: Which is to say, of course, that this exception was happening before, but when "enable just my code" is off, the debugging assistant (if enabled), will stop at this point when thrown.

joniba