none
WCF referencing other services and type conflicts RRS feed

  • Question

  • Hello,

    We have built a WCF service consuming itself data from multiple Java webservices. The WCF service thus acts as an aggregation of these services and is the single point to get/set data from our front-end application.

    A same type of data is returned by different methods in different Java webservices, let's call it Person:

    Example:

    JavaService1 - myMethod1() - returns: Person

    JavaService2 - myMethod2() - returns: Person

    Important note: Person is an abstract type in Java services.

    In WCF both Java service references are set to reuse types in referenced assemblies. The Java services WSDLs expose the type with the same namespace, this means the type is the same from an XML point of view.

    When referencing the WCF service in the front-end application, we get the Person type duplicated: Person and Person1.

    We cannot get rid of this behavior, so any help would be very welcome, thanks in advance!


    • Edited by Y. Cotton Monday, July 29, 2013 8:22 AM
    Friday, July 26, 2013 4:05 PM

Answers

  • Hi Y. Cotton,

    For your scenario, I think the duplicated type is due to the manner how Visual Studio "Add Service Reference" wizard will create proxy types based on service metadata. So even the types are the same from XML perspective, since you create two service references from two services, Visual Studo generate different types respectively.

    To overcome this issue, a simple and straight way is to manually open the generated code and modify the generated Service/Operation Contract to use the same type (for the operations on different service). The drawback is that everytime you update the Servicereference in Visual Studio, your changes will be overwritten.

    Another approach is to use SvcUtil.exe to generate the proxy out of Visual Studio. After that, you can manually modify the generated code to make the proxy of two services share the same types. By this way, you have to manually use svcutil.exe for proxy generation and update yourself.

    #ServiceModel Metadata Utility Tool (Svcutil.exe)
    http://msdn.microsoft.com/en-us/library/aa347733.aspx


    Please remember to mark the replies as answers if they help and unmark them if they provide no help.

    Thursday, August 1, 2013 4:13 PM
    Moderator

All replies

  • Hi,

    Could you please post some main code here?

    It will help to find the cause.

    Best Regards.


    Amy Peng
    MSDN Community Support | Feedback to us
    Develop and promote your apps in Windows Store
    Please remember to mark the replies as answers if they help and unmark them if they provide no help.


    Tuesday, July 30, 2013 8:37 AM
    Moderator
  • Hi,

    Sure, here is a summary that should help you understanding the problem.

    1) In the WCF service, in the reference.cs file generated from JavaService1 (let's call it like that)

        [System.Xml.Serialization.XmlIncludeAttribute(typeof(GroupOfPersons))]
        [System.Xml.Serialization.XmlIncludeAttribute(typeof(Company))]
        [System.Xml.Serialization.XmlIncludeAttribute(typeof(GenericPerson))]
        [System.Xml.Serialization.XmlIncludeAttribute(typeof(NaturalPerson))]
        [System.CodeDom.Compiler.GeneratedCodeAttribute("System.Xml", "4.0.30319.233")]
        [System.SerializableAttribute()]
        [System.Diagnostics.DebuggerStepThroughAttribute()]
        [System.ComponentModel.DesignerCategoryAttribute("code")]
        [System.Xml.Serialization.XmlTypeAttribute(Namespace="urn:mycompany:finance:services:common")]
        public abstract partial class Person: object, System.ComponentModel.INotifyPropertyChanged {
    
    // ....
    }

    2) In the same WCF service, in the reference.cs file generated from JavaService2

        [System.Xml.Serialization.XmlIncludeAttribute(typeof(GroupOfPersons))]
        [System.Xml.Serialization.XmlIncludeAttribute(typeof(Company))]
        [System.Xml.Serialization.XmlIncludeAttribute(typeof(GenericPerson))]
        [System.Xml.Serialization.XmlIncludeAttribute(typeof(NaturalPerson))]
        [System.CodeDom.Compiler.GeneratedCodeAttribute("System.Xml", "4.0.30319.1009")]
        [System.SerializableAttribute()]
        [System.Diagnostics.DebuggerStepThroughAttribute()]
        [System.ComponentModel.DesignerCategoryAttribute("code")]
        [System.Xml.Serialization.XmlTypeAttribute(Namespace="urn:mycompany:finance:services:common")]
        public abstract partial class Person: object, System.ComponentModel.INotifyPropertyChanged {
    }

    On the Java side, the Person class is defined once in a common namespace, and like you can see it is reference the same way in both Java services references on the WCF side.

    When I add a service reference to my WCF service in my front-end web application, it generates Person and Person1 like following:

        [System.Xml.Serialization.XmlIncludeAttribute(typeof(NaturalPerson))]
        [System.Xml.Serialization.XmlIncludeAttribute(typeof(GenericPerson))]
        [System.Xml.Serialization.XmlIncludeAttribute(typeof(GroupOfPersons))]
        [System.Xml.Serialization.XmlIncludeAttribute(typeof(Company))]
        [System.CodeDom.Compiler.GeneratedCodeAttribute("System.Xml", "4.0.30319.1009")]
        [System.SerializableAttribute()]
        [System.Diagnostics.DebuggerStepThroughAttribute()]
        [System.ComponentModel.DesignerCategoryAttribute("code")]
        [System.Xml.Serialization.XmlTypeAttribute(Namespace="urn:mycompany:finance:services:common")]
        public abstract partial class Person : object, System.ComponentModel.INotifyPropertyChanged {
    
    // ...
    
    }

        [System.CodeDom.Compiler.GeneratedCodeAttribute("System.Xml", "4.0.30319.1009")]
        [System.SerializableAttribute()]
        [System.Diagnostics.DebuggerStepThroughAttribute()]
        [System.ComponentModel.DesignerCategoryAttribute("code")]
        [System.Xml.Serialization.XmlTypeAttribute(TypeName="Person", Namespace="http://schemas.datacontract.org/2004/07/mycompany.finance.account.services.JavaSe" +
            "rvice2")]
        public partial class Person1 : object, System.ComponentModel.INotifyPropertyChanged {
     //...
    }

    So the first one looks correct, but we want to prevent the second one (Person1) from being generated.

    Many thanks in advance for your answers.

    Tuesday, July 30, 2013 10:01 AM
  • Hi,

    If in your WCF project you have a single Person class, then client should not get Person and Person1 different classes. Can you check your WCF proxy code, is it defining Person1 somewhere?


    One good question is equivalent to ten best answers.

    Tuesday, July 30, 2013 10:38 AM
  • Hello,

    Thank you for your answer but unfortunately Person1 is not defined anywhere in my own code, neither in the code of the WCF service nor in the code of the web front-end application consuming the service.

    But:

    Person1 type is automatically generated by Visual Studio in the WCF Service reference in the web front-end application and we cannot get rid of this behavior. And this is the case with plenty of other types in our solution. So I would be very grateful if someone could find a solution to my problem.

    Tuesday, July 30, 2013 12:04 PM
  • Anybody having an idea?

    Thank you

    Thursday, August 1, 2013 8:13 AM
  • Hi Y. Cotton,

    For your scenario, I think the duplicated type is due to the manner how Visual Studio "Add Service Reference" wizard will create proxy types based on service metadata. So even the types are the same from XML perspective, since you create two service references from two services, Visual Studo generate different types respectively.

    To overcome this issue, a simple and straight way is to manually open the generated code and modify the generated Service/Operation Contract to use the same type (for the operations on different service). The drawback is that everytime you update the Servicereference in Visual Studio, your changes will be overwritten.

    Another approach is to use SvcUtil.exe to generate the proxy out of Visual Studio. After that, you can manually modify the generated code to make the proxy of two services share the same types. By this way, you have to manually use svcutil.exe for proxy generation and update yourself.

    #ServiceModel Metadata Utility Tool (Svcutil.exe)
    http://msdn.microsoft.com/en-us/library/aa347733.aspx


    Please remember to mark the replies as answers if they help and unmark them if they provide no help.

    Thursday, August 1, 2013 4:13 PM
    Moderator