none
How to create Header with attributes, not elements RRS feed

  • Question

  • I created a web service that generates the following request:

    <soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:abc="http://www.abc.coop"   xmlns:xyz="http://schemas.datacontract.org/2004/07/xyz.Soa.BusinessObjects.EBPP">
       <soapenv:Header>
          <abc:abcGatewayMsgHeader>
             <xyz:AppType>?</xyz:AppType>
             <xyz:CompanyID>?</xyz:CompanyID>
             <xyz:SessionID>?</xyz:SessionID>
             <xyz:User>?</xyz:User>
             <xyz:Version>?</xyz:Version>
          </abc:abcGatewayMsgHeader>
       </soapenv:Header>
       <soapenv:Body>
          <abc:GetVersion/>
       </soapenv:Body>
    </soapenv:Envelope>

    However, I need the request to look like the following.  The 5 values must be attributes of abcGatewayMsgHeader instead of sub-elements.

    <soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:abc="http://www.abc.coop">
       <soapenv:Header>
          <abc:abcGatewayMsgHeader Version="?" CompanyID="?" SessionID="?" AppType="?" User="?"/>
       </soapenv:Header>
       <soapenv:Body>
          <abc:GetVersion/>
       </soapenv:Body>
    </soapenv:Envelope>

    For reference, this is my request class

    Namespace EBPP
    
        <MessageContract(WrapperName:="GetVersion")>
        Public Class GetVersionRequest
    
            <MessageHeader()>
            Public Property abcGatewayMsgHeader As New Header
    
            Public Sub New()
                MyBase.New()
            End Sub
    
        End Class
    
        Public Class Header
            Public Property Version As String
            Public Property CompanyID As String
            Public Property SessionID As String
            Public Property AppType As String
            Public Property User As String
    
            Public Sub New()
            End Sub
        End Class
    End Namespace

    This is my response class

    Namespace EBPP
    
        <MessageContract()>
        Public Class GetVersionResponse
    
            <MessageHeader()>
            Public Property abcGatewayMsgHeader As New Header
    
            <MessageBodyMember()>
            Public Property ReqBody As String
    
            Public Sub New()
                MyBase.New()
            End Sub
    
        End Class
    End Namespace

    Web service interface

    Namespace EBPPServices
    
        <ServiceContract(Namespace:="http://www.abc.coop")>
        Public Interface IEBPPServices
    
            <OperationContract()>
            Function GetVersion(request As EBPP.GetVersionRequest) As EBPP.GetVersionResponse
    
        End Interface
    End Namespace

    Service

    Namespace EBPPServices.web Public Class EBPPServices Implements IEBPPServices Public Function GetVersion(request As EBPP.GetVersionRequest) As EBPP.GetVersionResponse Implements IEBPPServices.GetVersion Dim res As New EBPP.GetVersionResponse res.abcGatewayMsgHeader.AppType = "SomeValue" res.abcGatewayMsgHeader.CompanyID = "SomeValue" res.abcGatewayMsgHeader.SessionID = "SomeValue" res.abcGatewayMsgHeader.User = "SomeValue" res.abcGatewayMsgHeader.Version = "SomeValue" res.ReqBody = "SomeValue" Return res End Function End Class End Namespace

    Any ideas?

    Tuesday, July 17, 2012 9:34 PM

Answers

  • Hello,

    Hello,

    This behaviour is because, your service is using standard WCF DataContractSerializer. For sake about 10% more speed,DataContractSerializer forgoes XmlAttribute and serialize everything as XmlElements even having [XmlAttribute] attributes on your data does not make difference. you need to specially ask for XmlSerializer either when creating proxy client using svcUtil.exe or by specifying [XmlSerailzerFormat] on your service implementation.

    So, To get desire output i modified your Contract a bit as well.

    Also, Mark your service interface with <XmlSerializerFormat> attribute.

    Public Class Header	
    <XmlAttribute>
    Public Property Version As String
    <XmlAttribute>
    Public Property CompanyID As String
    <XmlAttribute>
    Public Property SessionID As String
    <XmlAttribute>
    Public Property AppType As String
    <XmlAttribute>
    Public Property User As String
    Public Sub New()
    End Sub
    End Class

    This will produce output as below. Please ignore other values in that as it contains test data for me.

    <s:Envelope xmlns:s="http://www.w3.org/2003/05/soap-envelope">
    <s:Header>
      <Action s:mustUnderstand="1" xmlns="http://schemas.microsoft.com/ws/2005/05/addressing/none">http://schemas.cyclone.com/2011/03/services/Service/GetData</Action> 
      <h:abcGatewayMsgHeader Version="1.0" CompanyID="IGate" AppType="PMP" User="Abc" xmlns="http://schemas.cyclone.com/2011/03/data" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:h="http://schemas.cyclone.com/2011/03/data" /> 
      </s:Header>
      <s:Body xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" /> 
      </s:Envelope>
    Hope, this will help you out. Feel free to contact in case of query.

    If this post answers your question, please click Mark As Answer. If this post is helpful please click Mark as Helpful.

    • Marked as answer by Biff64 Thursday, July 19, 2012 1:52 PM
    Thursday, July 19, 2012 6:48 AM

All replies

  • Hello,

    Hello,

    This behaviour is because, your service is using standard WCF DataContractSerializer. For sake about 10% more speed,DataContractSerializer forgoes XmlAttribute and serialize everything as XmlElements even having [XmlAttribute] attributes on your data does not make difference. you need to specially ask for XmlSerializer either when creating proxy client using svcUtil.exe or by specifying [XmlSerailzerFormat] on your service implementation.

    So, To get desire output i modified your Contract a bit as well.

    Also, Mark your service interface with <XmlSerializerFormat> attribute.

    Public Class Header	
    <XmlAttribute>
    Public Property Version As String
    <XmlAttribute>
    Public Property CompanyID As String
    <XmlAttribute>
    Public Property SessionID As String
    <XmlAttribute>
    Public Property AppType As String
    <XmlAttribute>
    Public Property User As String
    Public Sub New()
    End Sub
    End Class

    This will produce output as below. Please ignore other values in that as it contains test data for me.

    <s:Envelope xmlns:s="http://www.w3.org/2003/05/soap-envelope">
    <s:Header>
      <Action s:mustUnderstand="1" xmlns="http://schemas.microsoft.com/ws/2005/05/addressing/none">http://schemas.cyclone.com/2011/03/services/Service/GetData</Action> 
      <h:abcGatewayMsgHeader Version="1.0" CompanyID="IGate" AppType="PMP" User="Abc" xmlns="http://schemas.cyclone.com/2011/03/data" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:h="http://schemas.cyclone.com/2011/03/data" /> 
      </s:Header>
      <s:Body xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" /> 
      </s:Envelope>
    Hope, this will help you out. Feel free to contact in case of query.

    If this post answers your question, please click Mark As Answer. If this post is helpful please click Mark as Helpful.

    • Marked as answer by Biff64 Thursday, July 19, 2012 1:52 PM
    Thursday, July 19, 2012 6:48 AM
  • Thanks Tejas, that is exactly what I needed.

    Thursday, July 19, 2012 1:54 PM