Friday, May 3, 2013

Service Reference Generation using svcutil.exe

Duplicate objects being generated.

When working with generating a single service reference code file for multiple services I encountered an issue where one of the services being used exposes a System.Data.Dataset as the return datatype. The issue i had was that the generated objects seemed to get duplicated and generated in two different ways as shown and below,
 
The code below is gerated via the DataContracSerializer as you can clearly say based on some of the attributes used in the class and properties (i.e. line 3 and 23).
[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.CodeDom.Compiler.GeneratedCodeAttribute("System.Runtime.Serialization", "4.0.0.0")]
[System.Runtime.Serialization.DataContractAttribute(Name="Person", Namespace="http://tempuri.org/")]
public partial class Person : object, System.Runtime.Serialization.IExtensibleDataObject
{
 
 private System.Runtime.Serialization.ExtensionDataObject extensionDataField;
 
 private string NameField;
 
 public System.Runtime.Serialization.ExtensionDataObject ExtensionData
 {
  get
  {
   return this.extensionDataField;
  }
  set
  {
   this.extensionDataField = value;
  }
 }
 
 [System.Runtime.Serialization.DataMemberAttribute(EmitDefaultValue=false)]
 public string Name
 {
  get
  {
   return this.NameField;
  }
  set
  {
   this.NameField = value;
  }
 }
}
 
The code below is gerated via the XMLSerializer as you can clearly say based on some of the attributes used in the class and properties (i.e. line 5 and 12).
[System.CodeDom.Compiler.GeneratedCodeAttribute("svcutil", "4.0.30319.1")]
[System.SerializableAttribute()]
[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.ComponentModel.DesignerCategoryAttribute("code")]
[System.Xml.Serialization.XmlTypeAttribute(Namespace="http://tempuri.org/")]
public partial class Person
{
    
    private string nameField;
    
    /// 
    [System.Xml.Serialization.XmlElementAttribute(Order=0)]
    public string Name
    {
        get
        {
            return this.nameField;
        }
        set
        {
            this.nameField = value;
        }
    }
}
 
The reason for this duplication is that one of the services I was interfacing with had the type System.Data.Dataset being returned from a service method. Hence the svcutil tries to use the DataContractSerilizer schema importer tries to infer the System.Data.Dataset and fails to use the XML schema associated with it and resolves to XMLSerializer to serialize the objects for this service.

Overcoming the problem

It is clear that the DataContractSerializer cannot infer XML schema defined types. Hence in order to overcome this problem the alternative is to force svcutil to use the XMLSerializer for all the services being referenced like so,
 
svcutil /r:C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\System.Data.dll /serializer:XmlSerializer /out:MyService.cs /namespace:http://tempuri.org/,MyService.MyServiceReference https://www.mydomain.com/service1.asmx https://www.mydomain.com/service2.asmx
 
With the above command you should be able to generate the service code that will solve the duplicate objects being generated. However there is another minor issue, which is that the proxy objects generated do not fall/associate into the above provided namespace MyService.MyServiceReference instead is placed in the global namespace and will cause issues if you have similar names defined elsewhere in your solution.
 
To fix this is just a minor hack, if you analyze the generated MyService.cs file, you will notice that the namespace only wraps the service functions, where all you need to do is move the namespace definition to the beginning of the file so that it covers the proxy object definitions. This should give you a complete service reference when referring to multiple services that are required to be XMLSerialized due to the afore mentioned reason.

About Me

I am a software developer with over 7+ years of experience, particularly interested in distributed enterprise application development where my focus is on development with the usage of .Net, Java and any other technology that fascinate me.