none
Supply a different namespace for a DataMember in a WCF DataContract RRS feed

  • Question

  • This is an example of a VB Class for one of my data contracts:

    <System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "2.0.50727.3038"), _
     System.SerializableAttribute(), _
     System.Diagnostics.DebuggerStepThroughAttribute(), _
     System.ComponentModel.DesignerCategoryAttribute("code"), _
     System.Xml.Serialization.XmlTypeAttribute([Namespace]:="http://www.example.com/NS1"), _
     System.Runtime.Serialization.DataContractAttribute([Namespace]:="http://www.example.com/NS1")> _
    Partial Public Class SomeType
        ...
        Private someMemberField As String
        ... 
    
        <DataMember(Order:=4)> _
        Public Property SomeMember() As String
            Get
                Return Me.someMemberField
            End Get
            Set(value As String)
                Me.someMemberField = value
            End Set
        End Property
    End Class

    WSDL becomes (namespace is http://www.example.com/NS1 as expected):

    <xs:complexType name="SomeType">
      <xs:sequence>
        ...
        <xs:element minOccurs="0" name="SomeMember" nillable="true" type="xs:string"/>
        ...
      </xs:sequence>
    </xs:complexType>

    A XML example is:

    <SomeType xmlns="htttp://www.example.com/NS1">
       ...
       <SomeMember>some text</SomeMember>
       ...
    </Sometype>

    This is perfect to me. However my client (which is not WCF) needs a different namespace for the DataMember. A XML example like this:

    <SomeType xmlns="http://www.example.com/NS1">
       ...
       <SomeMember xmlns="http://www.example.com/NS2">some text</SomeMember>
       ...
    </Sometype>

    I believe that the WSDL should look similar to this:

    <xs:complexType name="SomeType">
      <xs:sequence>
        ...
        <xs:element minOccurs="0" name="SomeMember" nillable="true" type="xs:string" xmlns:q1="http://www.example.com/NS2"/>
        ...
      </xs:sequence>
    </xs:complexType>

    I know how to do it for complex data types.

    All I have to do is change the namespace in the DataContractAttribute of the respective class, which I did for the members that aren't primitive data types.

    Is this possible for primitive data types such as String?

    I can't change namespaces in DataMembers and I can't figure out any other way of setting a different namespace for a primitive data type.

    However, XML examples generated from XSD do include namespaces in primitive data type members.

    Does anyone know how can I get something like this using WCF?

    <SomeType xmlns="http://www.example.com/NS1">
       ...
       <SomeMember xmlns="http://www.example.com/NS2">some text</SomeMember>
       ...
    </Sometype>

    Thanks in advance,

    Fernando Martins.

    Thursday, June 26, 2014 8:50 AM

Answers

  • Solution found!

    Using a service contract like this:

        <ServiceContract(Namespace:="http://www.example.com/NS1")>
        Public Interface MyServiceContract
            ... 
        End Interface

    XML for the class SomeType looks like this:

        <SomeType xmlns="htttp://www.example.com/NS1">
           ...
           <SomeMember>some text</SomeMember>
           ...
        </Sometype>

    Adding the <XmlSerializerFormat()> to the service contract:

        <ServiceContract(Namespace:="http://www.example.com/NS1")>
        <XmlSerializerFormat()>
        Public Interface MyServiceContract
            ... 
        End Interface

    XML becomes like this (namespaces are displayed for each member):

        <SomeType>
           ...
           <SomeMember xmlns="htttp://www.example.com/NS1">some text</SomeMember>
           ...
        </Sometype>

    Then, the third-party client assigns for the SomeType the same namespace where SomeType is encapsulated.

    Monday, June 30, 2014 5:06 PM

All replies

  • Hi,

    Maybe we can try to define subdatacontracts in different namespaces and use them as members of another datacontract, but we can't control the individual member names and/or shapes.

    Also please try to refer to this similar thread:
    #Change XML Namespace of DataMember:
    http://stackoverflow.com/questions/17067180/change-xml-namespace-of-datamember .


    Best Regards,
    Amy Peng

    We are trying to better understand customer views on social support experience, so your participation in this interview project would be greatly appreciated if you have time. Thanks for helping make community forums a great place.
    Click HERE to participate the survey.

    Friday, June 27, 2014 10:43 AM
    Moderator
  • Hi Amy,
    Thanks for your reply.
    The other similar thread deals with a complex data type (SharedType).
    In these cases, is very easy to change their namespaces.
    But, as you said, we can't change that for an individual member.
    I got a suggestion of making a copy of the wsdl file, edit it and use this customized wsdl in my service.
    I've done this, adding the namespace NS2 to the string SomeMember:

        <xs:complexType name="SomeType">
          <xs:sequence>
            ...
            <xs:element minOccurs="0" name="SomeMember" nillable="true" type="q1:string" xmlns:q1="http://www.example.com/NS2"/>
            ...
          </xs:sequence>
        </xs:complexType>

    Then, in the schema of the namespace NS2, I've added:

        <xs:simpleType name="string">
          <xs:restriction base="xs:string"/>
        </xs:simpleType>

    Finally, I edited the web config file:

        <behaviors>
          <serviceBehaviors>
            <behavior name="myBehavior">
              <serviceMetadata httpGetEnabled="true" externalMetadataLocation="http://myServerURL/MySchemas.wsdl" />
              <serviceDebug includeExceptionDetailInFaults="true"/>
            </behavior>
          </serviceBehaviors>
        </behaviors>
    
        <services>
          <service name="MyServiceNS.MyServiceName" behaviorConfiguration="myBehavior">
            <endpoint address="" binding="basicHttpBinding" contract="MyServiceNS.MyServiceContract"/>
            <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"/>
          </service>
        </services>
    When I type http://myServerURL.pt/MyServiceName.svc?wsdl in the browser I can see the changes I made.
    However, WCF Test Client completly ignores the namespace NS2 of the String SomeMember, and everything is working just like before the customized wsdl.
    I still don't know if this solution worked for the guys who are building the client.
    I'm wating for an answer.

    All the best,
    Fernando Martins.

    Saturday, June 28, 2014 3:54 PM
  • Solution found!

    Using a service contract like this:

        <ServiceContract(Namespace:="http://www.example.com/NS1")>
        Public Interface MyServiceContract
            ... 
        End Interface

    XML for the class SomeType looks like this:

        <SomeType xmlns="htttp://www.example.com/NS1">
           ...
           <SomeMember>some text</SomeMember>
           ...
        </Sometype>

    Adding the <XmlSerializerFormat()> to the service contract:

        <ServiceContract(Namespace:="http://www.example.com/NS1")>
        <XmlSerializerFormat()>
        Public Interface MyServiceContract
            ... 
        End Interface

    XML becomes like this (namespaces are displayed for each member):

        <SomeType>
           ...
           <SomeMember xmlns="htttp://www.example.com/NS1">some text</SomeMember>
           ...
        </Sometype>

    Then, the third-party client assigns for the SomeType the same namespace where SomeType is encapsulated.

    Monday, June 30, 2014 5:06 PM