Tuesday, 9 July 2013

PreGenerated XmlSerializers.dll in ASP.Net Web Service - Increases Web Service Performance

In .Net , XmlSerializers Generates a temprory  assembly for serializing and deserializing your class for Performance reasons, It can be generated on the runtime or pregenerated the assembly during compilation of your ASP.Net web service.

How it is Works in Asp.Net web service ?

When we call a web service from a client for the First time , you will notice that Asp.net service take lit bit time to load, this is because it has to generate the XmlSerializer.dll at the runtime in system temp location    "%SYSTEMROOT%\Temp " for the first time invocation .After the first invocation it will become better because the service have the code to Serialize and deSerialize the Response .

One each request it will generate the dll at runtime in temp location, If the dll is not present there in Temp folder. some times this dll will be deleted by AntiVirus by consider it as Serialization.dll virus in temp folder.

To see the Generated XmlSerializer.dll code we can enable it through web.Config. Add the following code in the web.config file of your Asp.Net web service application . Enable the debug mode.

          <add name="XmlSerialization.Compilation" value="1" />

Now you can see the XmlSerialization.dll in the temp location, if you want to generate it at particular path, then that can be done by following code in  web.Config. Create "c:\\dllfolder" directory and Make sure your hosting application have access rights to the folder. c:\\dllfolder

  <xmlSerializer tempFilesLocation="c:\\dllfolder"/> 

During build a project in VS the XmlSerialzer.dll is auto generated. This can be stopped by following steps.
  1. In VS, right-click your project file and select "Properties"
  2. Click the "Build" tab
  3. Change the "Generate serialization assembly" dropdown from "Auto" to "Off"
  4. Rebuild and it will be gone

Now Let we start how to PreGenerate the XmlSerialization.dll .

Overall Steps for the PreGenerated XmlSerializers.dll 
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 Serialization dll for the proxy.
5. Remove out the all occurrences of XmlIncludeAttribute from the c# proxy class.
6. Insert XmlSerializerAssemblyAttribute present in the generated serialization dll.
7. Recompile the proxy dll with the reference to the serialization dll.

Step 1
           Create a Sample Calculator service and host in local server.Code for Calculator service is mention below.

Here due to avoid manual step of generate the proxy class i have create a client application which will create proxy automatically by reference the web service.
 Service address is "http://localhost:30967/Calculator.asmx"

Step 2
           Now call this web Service from your client Application by adding web Reference using following steps.

This step is for client application which are in .Net Project 2.0
 2.1 Right click your project in VS.
 2.2 Select Add Web Reference.
 2.3 Paste your hosted URL for this Calculator application.
 2.4 Give Web Reference name and add it

This step for Client application which are in .Net Project 3.0 or 3.5
 1. Right click your project in VS.
 2. Select Add Service Reference .
 3. click the Advance Button which is present in bottom of the screen. which will launch a another screen.
 4. Click the Add Web Reference button , follow the steps from 2.3 to 2.4

Step 3. 
        Now go to visual studio command prompt and iterate to the project sub folders , which contains the proxy for service class 

       In My application it is named as Reference.cs , you can can see the service class name inside the file. This is the proxy class.Copy the file and create a new sub folder and paste the file there with rename the file as Calculator.cs

 Step 3.1  Open that cs file and change the constructor like add an parameter "string url"

 Step 3.2  Comment the global:: line and assign the url input parameter to This.Url
  public Calculator(string url)
            this.Url = url;   //global::SampleProject.Properties.Settings.Default.SampleProject_CalSer_Calculator;
       Now execute the following command in command prompt of VS, This will create a library  in the visual studio installation path inside VC folder.
csc  /t:library  /out:calser.dll "C:\SampleProject\Web References\CalSer\Calculator.cs"

Step 4 :
             Following  Use the sgen tool to pre-generate the XmlSerializers.dll for the Calser.dll . Dll will be generated in the same folder where Calser.dll presents.Generation of dll will take few seconds.

Now execute the following command in command prompt of VS

             sgen /p  "C:\SampleProject\Web References\cal\Calser.dll"

Step 5:
         Open the Calculator.cs and comment out all occurrences of  a particular attribute present in file , which is very important “[System.Xml.Serialization.XmlIncludeAttribute”

Step 6:
          Add the attribute to the existing attribute which is present on top of the proxy class ,This attribute will tell that an XmlSerializer.dll is binded to this proxy class this should be called at runtime on each invocation “[System.Xml.Serialization.XmlSerializerAssemblyAttribute(AssemblyName = "calser.XmlSerializers")]”

 [System.Xml.Serialization.XmlSerializerAssemblyAttribute(AssemblyName = "calser.XmlSerializers")]
public partial class Calculator : System.Web.Services.Protocols.SoapHttpClientProtocol 


Step 7:
       Now again compile and generate a Calser.dll which consisits reference of XmlSerializer.Dll in proxy class ,Dll is generated in the VC folder inside the visual studio installation directory

       Now execute the following command in command prompt of VS
csc  /t:library  /out:calser.dll "C:\SampleProject\Web References\CalSer\Calculator.cs"

Step 8: 
        Now Add the Reference Calser.dll to your Project and call the Constructor of that class by passing the valid Url, You can see the difference in performance of calling a getting a response from ASP.NET Webserivce

             CalSer.Calculator addop = new CalSer.Calculator(@"http://localhost:30967/Calculator.asmx");
            CalSer.CalResponse addres = addop.Add(1020);

         Thats it, From this article you can find out how we can improve the performance of Asp.Net Web Service call.

Note :
    1. Whenever the service code is changes ,you have to recompile the Dll.