Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Generating an Xml Serialization assembly as part of my build

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.

like image 261
Adam Tegen Avatar asked Sep 25 '08 16:09

Adam Tegen


People also ask

What does generate serialization Assembly do?

The serialization assembly improves the startup performance of a XmlSerializer when it serializes or deserializes objects of the specified types.

What is the correct way of using XML serialization?

As with the CreatePo method, you must first construct an XmlSerializer, passing the type of the class to be deserialized to the constructor. Also, a FileStream is required to read the XML document. To deserialize the objects, call the Deserialize method with the FileStream as an argument.

What is the basic difference between SOAP serialization and XML serialization?

XML serialization can also be used to serialize objects into XML streams that conform to the SOAP specification. SOAP is a protocol based on XML, designed specifically to transport procedure calls using XML. To serialize or deserialize objects, use the XmlSerializer class.

How to rebuild the XML serialization Assembly for debug or release?

This will leverage sgen.exe directly to rebuild the Xml Serialization assembly every time you build your project for Debug or Release. Look in the properties on the solution. On the build tab at the bottom there is a dropdown called "Generate Serialization assembly" This does not appear to be producing anything. you have to toggle it to "On".

How do I generate serialization Assembly from a class library?

Ensure * Solution Explorer is opened. Right-click on the ClassLibrary1 (Project Name), select Properties Go directly into the Build tab, at the bottom of the screen, for Generate serialization assembly, change the selection to On (default is Auto ). Save the properties and Build the project. You will see the above error in the output window:

How do I serialize an object in XML?

Introducing XML Serialization. To serialize all an object's fields and properties, both public and private, use the DataContractSerializer instead of XML serialization. The central class in XML serialization is the XmlSerializer class, and the most important methods in this class are the Serialize and Deserialize methods.

What is the XML serializer generator tool?

The XmlSerializer creates C# files and compiles them into .dll files to perform this serialization. In .NET Framework 2.0, the XML Serializer Generator Tool (Sgen.exe) is designed to generate these serialization assemblies in advance to be deployed with your application and improve startup performance.


2 Answers

As Martin has explained in his answer, turning on generation of the serialization assembly through the project properties is not enough because the SGen task is adding the /proxytypes switch to the sgen.exe command line.

Microsoft has a documented MSBuild property which allows you to disable the /proxytypes switch and causes the SGen Task to generate the serialization assemblies even if there are no proxy types in the assembly.

SGenUseProxyTypes

A boolean value that indicates whether proxy types should be generated by SGen.exe. The SGen target uses this property to set the UseProxyTypes flag. This property defaults to true, and there is no UI to change this. To generate the serialization assembly for non-webservice types, add this property to the project file and set it to false before importing the Microsoft.Common.Targets or the C#/VB.targets

As the documentation suggests you must modify your project file by hand, but you can add the SGenUseProxyTypes property to your configuration to enable generation. Your project files configuration would end up looking something like this:

  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|x86' ">     <!-- Snip... -->     <GenerateSerializationAssemblies>On</GenerateSerializationAssemblies>     <SGenUseProxyTypes>false</SGenUseProxyTypes>   </PropertyGroup>   <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|x86' ">     <!-- Snip... -->     <GenerateSerializationAssemblies>On</GenerateSerializationAssemblies>     <SGenUseProxyTypes>false</SGenUseProxyTypes>   </PropertyGroup> 
like image 166
heavyd Avatar answered Oct 25 '22 01:10

heavyd


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.

like image 25
flipdoubt Avatar answered Oct 25 '22 03:10

flipdoubt