Generating an Xml Serialization assembly as part of my build Generating an Xml Serialization assembly as part of my build xml xml

Generating an Xml Serialization assembly as part of my build


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>


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.


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 butthen 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.