none
Types duplicated by svcutil when a typed dataset is used

    Question

  •  

    I have a very bizarre problem whereby a service client that has been working just fine up until today now won't compile because of a single new operation that was added. That operation happens to return a typed dataset, and causes svcutil to generate a proxy class that includes two definitions of the same type, from a different service. To wit:

     

    Code Snippet

    [ServiceContract(Name = "Service1")]

    public interface IService1 {

    [OperationContract]

    InstanceTag[] GetInstances();

    }

     

    [ServiceContract(Name = "Service2")]

    public interface IService2 {

    [OperationContract]

    MyDataSet GetData();

    }

     

     

     

    cause svcutil to generate both:

     

    Code Snippet

    [System.CodeDom.Compiler.GeneratedCodeAttribute("svcutil", "3.0.4506.30")]

    [System.SerializableAttribute()]

    [System.Diagnostics.DebuggerStepThroughAttribute()]

    [System.ComponentModel.DesignerCategoryAttribute("code")]

    [System.Xml.Serialization.XmlTypeAttribute(Namespace="blah" +

    "")]

    public partial class InstanceTag : object, System.ComponentModel.INotifyPropertyChanged

    {

    ...

    }

     

     

     

    and

     

    Code Snippet

    [System.CodeDom.Compiler.GeneratedCodeAttribute("System.Runtime.Serialization", "3.0.0.0")]

    [System.Runtime.Serialization.DataContractAttribute(Namespace="blah" +

    "")]

    public partial class InstanceTag : object, System.Runtime.Serialization.IExtensibleDataObject, System.ComponentModel.INotifyPropertyChanged

    {

    ...

    }

     

     

     

    This clearly won't even compile.

     

    If I exclude the new DataSet-returning operation from Service2, svcutil generates a proxy that only contains the second definition of InstanceTag, and the service client compiles and runs just fine.

     

    Is there something I can do to prevent this duplicate definition?

    Tuesday, August 28, 2007 4:46 PM

Answers

  • I seem to remember an issue here in WCF's XmlSerializer fallback logic.

     

    It goes something like this:

     

    - The default DataContractSerializer does not support importing typed dataset classes. They must be shared between client and server and referenced using the /r switch on svcutil.exe - see the end of http://msdn2.microsoft.com/en-us/library/aa347876.aspx for more details. This is actually by design. So, one way you could solve it (if sharing the type is an option) is to use the /r switch to point to the assembly containing the typed dataset.

     

    - If you don't use /r, the DataContractSerializer schema importer fails to import the typed dataset, and falls back to the XmlSerializer. Unfortunately, as far as I can tell there is a bug here - Service2 falls back to XmlSerializer, Service1 uses DataContractSerializer, and type duplication results. One way you can work around this is to force XmlSerializer fallback for the entire service - use the /serializer:XmlSerializer switch on svcutil.exe

     

    As usual, if the workarounds suggested here don't work and the issue is blocking for you / causing significant business impact, please contact Microsoft Product Support to discuss your options.

     

    Tuesday, August 28, 2007 10:11 PM
    Moderator

All replies

  •  

    I should add that my typed dataset does NOT contain any columns of type InstanceTag.
    Tuesday, August 28, 2007 4:49 PM
  • I seem to remember an issue here in WCF's XmlSerializer fallback logic.

     

    It goes something like this:

     

    - The default DataContractSerializer does not support importing typed dataset classes. They must be shared between client and server and referenced using the /r switch on svcutil.exe - see the end of http://msdn2.microsoft.com/en-us/library/aa347876.aspx for more details. This is actually by design. So, one way you could solve it (if sharing the type is an option) is to use the /r switch to point to the assembly containing the typed dataset.

     

    - If you don't use /r, the DataContractSerializer schema importer fails to import the typed dataset, and falls back to the XmlSerializer. Unfortunately, as far as I can tell there is a bug here - Service2 falls back to XmlSerializer, Service1 uses DataContractSerializer, and type duplication results. One way you can work around this is to force XmlSerializer fallback for the entire service - use the /serializer:XmlSerializer switch on svcutil.exe

     

    As usual, if the workarounds suggested here don't work and the issue is blocking for you / causing significant business impact, please contact Microsoft Product Support to discuss your options.

     

    Tuesday, August 28, 2007 10:11 PM
    Moderator
  • OK thanks, that makes sense. I'm fairly sure that sharing the dataset with the client will be the best way to solve this, since it's auto-generated and (necessarily) has no lower-level server-side dependencies -- I'll give that a go.

     

    What would be the implications of forcing XmlSerializer, given that my channel is NetTcp? I assume performance would be impacted?

     

    Wednesday, August 29, 2007 12:44 AM
  • Why not just send it as an untyped dataset ( you can cast it) ?  Than in the proxy layer of the client convert to your typed dataset - would seem a lot quicker to implement features and a lot less trouble. 

     

    Regards,

     

    Ben

    Wednesday, August 29, 2007 1:13 AM
  • Ben,

     

    My typed dataset contains (non-primitive) types of my own definition, that are shared between the client and the server. Would the dataset still be serialized/deserialized correctly if I cast away my specific typed dataset?

     

    Wednesday, August 29, 2007 1:26 AM