Tuesday 19 October 2010

Pre-generate Xml Serialisation of a WebService Proxy to speed load time

Problem

Microsoft .NET 2+ will dynamically create Xml Serialisation code when instantiating a WebService proxy.  If the WebService is a large one with many types and methods defined then the load time can be unacceptably slow.

Solution

The solution is to use .NET tools to pre-generate the serialisation code and then replace the serialisation attributes in the proxy with a reference to the generated dll.

The following PowerShell script automates the process for a WSDL file, MyService.wsdl:

# This Powershell script assists in the creation of a WebService proxy that loads in a reasonable time.
# .NET will usually dynamically generate Xml Serialization code when the service proxy is instantiated.
# This results in a ~1min delay.
# In order to speed the load time it is necessary to pre-generate the Xml Serialization code.
# You can then replace the Xml Serialization attributes with a single reference to the pre-compiled dll.
# The script below automates the process.

Write-Progress -activity 'Building Proxy' -status 'Progress->' -percentcomplete 0 -currentOperation 'Set Enviromnent'
$env:path = "C:\WINDOWS\system32; C:\WINDOWS; C:\WINDOWS\system32\WindowsPowerShell\v1.0; C:\WINDOWS\Microsoft.NET\Framework\v4.0.30319; C:\Program Files\Microsoft SDKs\Windows\v7.0A\bin\NETFX 4.0 Tools; C:\Program Files\Microsoft SDKs\Windows\v7.0A\bin"

Write-Progress -activity 'Building Proxy' -status 'Progress->' -percentcomplete 1 -currentOperation 'Create basic proxy'
wsdl /n:MyWebServiceProxy MyWebService.wsdl

Write-Progress -activity 'Building Proxy' -status 'Progress->' -percentcomplete 10 -currentOperation 'Compile basic proxy'
csc.exe /t:library /out:MyWebServiceProxy.dll MyWebServiceProxy.cs

Write-Progress -activity 'Building Proxy' -status 'Progress->' -percentcomplete 20 -currentOperation 'Build proxy serialisation'
sgen.exe /p /force MyWebServiceProxy.dll

Write-Progress -activity 'Building Proxy' -status 'Progress->' -percentcomplete 50 -currentOperation 'Remove XmlIncludeAttribute from proxy'
Get-Content MyWebServiceProxy.cs | % {$_ -replace '\[System\.Xml\.Serialization\.XmlIncludeAttribute', '//[System.Xml.Serialization.XmlIncludeAttribute'} | Set-Content -path MyWebServiceProxy_SerialisationRemoved.cs

Write-Progress -activity 'Building Proxy' -status 'Progress->' -percentcomplete 70 -currentOperation 'Add XmlSerializerAssemblyAttribute to proxy'
Get-Content MyWebServiceProxy_SerialisationRemoved.cs | % {$_ -replace 'public partial class MyWebService', '[System.Xml.Serialization.XmlSerializerAssemblyAttribute(AssemblyName = "MyWebServiceProxy.XmlSerializers")] public partial class MyWebService'} | Set-Content -path MyWebServiceProxy_SerialisationAdded.cs

Write-Progress -activity 'Building Proxy' -status 'Progress->' -percentcomplete 90 -currentOperation 'Compile new proxy'
csc.exe /t:library /out:MyWebServiceProxy.dll MyWebServiceProxy_SerialisationAdded.cs

Write-Progress -activity 'Building Proxy' -status 'Progress->' -percentcomplete 100 -currentOperation 'Finished.'



You’ll need to change the file and class names appropriately for your case or perhaps add parameters to the script.



 



What’s going on



Step by step:




  1. Add the locations of the tools used to the path environment variable.


  2. Use wsdl.exe .NET SDK utility to generate the proxy c# code file from the wsdl file.


  3. Compile the c# proxy into a dll.


  4. Use sgen.exe .NET SDK utility to generate an Xml Serialisation dll for the proxy.


  5. Using a regular expression strip out the XmlIncludeAttribute from the c# proxy.


  6. Using a regular expression insert a XmlSerializerAssemblyAttribute referencing the generated serialisation dll.


  7. Recompile the proxy dll with the reference to the serialisation dll.



References



With thanks to http://www.sharepoint-stuff.com/?p=199



Technorati Tags: ,

No comments: