locked
Soap header XML manipulation in .NET 2.0

    Question

  • Hi I have given a task to add two fields (__UserName/__SessionID) in a soap header.  The result soap header should look similar to this:

    <s:Envelope xmlns:s="http://www.w3.org/2003/05/soap-envelope" xmlns:a="http://www.w3.org/2005/08/addressing">
    <s:Header>
    <a:Action s:mustUnderstand="1">http://abc/xyz</a:Action>
    <__UserName xmlns=http://abc>xxxxxxx</__UserName>
    <__SessionID xmlns=http://abc>36edf379-708c-4056-b7d8-3bdaa4c6d172</__SessionID>.............
    </s:Header>

    This soap header is added to a WFC proxy class.  I have created a new soapheader class like this:

    <System.SerializableAttribute(), _
            System.ComponentModel.DesignerCategoryAttribute("code"), _
             System.Xml.Serialization.XmlTypeAttribute([Namespace]:="http://abc/"), _
             System.Xml.Serialization.XmlRootAttribute([Namespace]:="http://abc/", IsNullable:=False)> _
        Partial Public Class mySoapHeader
            Inherits System.Web.Services.Protocols.SoapHeader

            Private __UserNameField As System.Xml.XmlAttribute
            Private __SessionIDField As System.Xml.XmlAttribute

            Private __strUserNameValue As String
            Private __strSessionIDValue As String

                   <System.Xml.Serialization.XmlElement([Namespace]:="http://abc/")> _
            Public Property __UserName() As String
                Get
                    Return __strUserNameValue
                End Get
                Set(ByVal value As String)
                    __strUserNameValue = value
                    '__UserNameField.Value = __strUserNameValue
                End Set
            End Property

            <System.Xml.Serialization.XmlElement([Namespace]:="http://abc/")> _
            Public Property __SessionID() As String
                Get
                    Return __strSessionIDValue
                End Get
                Set(ByVal value As String)
                    __strSessionIDValue = value
                    '__SessionIDField.Value = __strSessionIDValue
                End Set
            End Property
         End Class

    And, at the declaration of a proxy class webmethod, I have added this:

    <System.Web.Services.Protocols.SoapDocumentMethodAttribute("http://abc/xyz", RequestNamespace:="http:/abc", ResponseNamespace:="http://abc", Use:=System.Web.Services.Description.SoapBindingUse.Literal, ParameterStyle:=System.Web.Services.Protocols.SoapParameterStyle.Wrapped), _
            System.Web.Services.Protocols.SoapHeader("xtraSoapHeader")> _
    Public Function CallThis

    The xtraSoapHeader class is declared as below:

    Private _mySoapHeader As New mySoapHeader()

            <System.Xml.Serialization.XmlAnyAttributeAttribute()> _
            Public Property xtraSoapHeader() As mySoapHeader
                Get
                    Return Me._mySoapHeader
                End Get

                Set(ByVal value As mySoapHeader)
                    Me._mySoapHeader = value
                End Set
            End Property

     

    It all seems to be OK but the outcome Soap Header is like this:

    <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
    <soap:Header>
           <mySoapHeader
    soap:mustUnderstand="1" xmlns="http://abc/">
                   <__UserName
    xmlns="http://abc/">xxxxxxxxx</__UserName>
                   <__SessionID
    xmlns="http://abc/">someValue</__SessionID>
            </mySoapHeader>
    </soap:Header>

    :

    As you can see, the code create a new element "mySoapHeader" INSIDE <soap:Header> which is the wrong location....
    Can anyone tell me how to make the two attributes appear under <soap:header> like this:

    <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
    <soap:Header>
           
            <__UserName xmlns="http://abc/">xxxxxxxxx</__UserName>
                   <__SessionID
    xmlns="http://abc/">someValue</__SessionID>
    </soap:Header>

    :

     

    Thanks heap.  I was told I might need to write customise serialization..but I have no idea......panic

    Wai-man


    --- WML ---
    Wednesday, October 13, 2010 7:54 AM

Answers

  • I have 100% fudged it:

    Here what I have done:

    Instead of create mySoapHeader, I created TWO separate classes using the names I suppose to pass into the soapHeader:

    <System.SerializableAttribute(), _
            System.ComponentModel.DesignerCategoryAttribute("code"), _
             System.Xml.Serialization.XmlTypeAttribute([Namespace]:="http://abc"), _
             System.Xml.Serialization.XmlRootAttribute([Namespace]:="http://abc", IsNullable:=False)> _
             Partial Public Class __UserName
            Inherits System.Web.Services.Protocols.SoapHeader

            <System.Xml.Serialization.XmlText()> _
            Public UserName As String
        End Class

        <System.SerializableAttribute(), _
            System.ComponentModel.DesignerCategoryAttribute("code"), _
             System.Xml.Serialization.XmlTypeAttribute([Namespace]:="http://abc"), _
             System.Xml.Serialization.XmlRootAttribute([Namespace]:="http://abc", IsNullable:=False)> _
             Partial Public Class __SessionID
            Inherits System.Web.Services.Protocols.SoapHeader

            <System.Xml.Serialization.XmlText()> _
            Public SessionID As String
        End Class

    As you can see, UserName and SessionID are the values of "__UserName" and "__SessionID" respectively....

    I then declared two phantom soapHeader classes in the proxy class:

    Private _mySoapHeader As New __UserName()
            Private _mySoapHeader2 As New __SessionID()

            <System.Xml.Serialization.XmlAnyAttributeAttribute()> _
            Public Property xtraSoapHeader() As __UserName
                Get
                    Return Me._mySoapHeader
                End Get

                Set(ByVal value As __UserName)
                    Me._mySoapHeader = value
                End Set
            End Property
            <System.Xml.Serialization.XmlAnyAttributeAttribute()> _
            Public Property xtraSoapHeader2() As __SessionID
                Get
                    Return Me._mySoapHeader2
                End Get

                Set(ByVal value As __SessionID)
                    Me._mySoapHeader2 = value
                End Set
            End Property

    and then added the declaration above the webmethod of the proxy class that I need to serialize the soap header:

    <System.Web.Services.Protocols.SoapDocumentMethodAttribute("http://abc/blah", RequestNamespace:="http://abc", ResponseNamespace:="http://abc", Use:=System.Web.Services.Description.SoapBindingUse.Literal, ParameterStyle:=System.Web.Services.Protocols.SoapParameterStyle.Wrapped), _
            System.Web.Services.Protocols.SoapHeader("xtraSoapHeader"), _
            System.Web.Services.Protocols.SoapHeader("xtraSoapHeader2")> _
            Public Function blah

    Seeing double?  So am I! But it works... it only gives me the soapHeader I want!!

    <soap:Header>
                   <__UserName xmlns="http://abc/">xxxxxxxxx</__UserName>
                   <__SessionID xmlns="http://abc/">someValue</__SessionID>
      </soap:Header>

    I know it is not the best but I am using .NET 2.0 here (!) and I am running out of time for this project...so I don't care....please let me know if there is better wahy to achieve this.

    Thanks for reading this.

     


    --- WML ---
    • Marked as answer by WML-AUS Wednesday, October 13, 2010 9:13 AM
    Wednesday, October 13, 2010 9:12 AM

All replies

  • I have 100% fudged it:

    Here what I have done:

    Instead of create mySoapHeader, I created TWO separate classes using the names I suppose to pass into the soapHeader:

    <System.SerializableAttribute(), _
            System.ComponentModel.DesignerCategoryAttribute("code"), _
             System.Xml.Serialization.XmlTypeAttribute([Namespace]:="http://abc"), _
             System.Xml.Serialization.XmlRootAttribute([Namespace]:="http://abc", IsNullable:=False)> _
             Partial Public Class __UserName
            Inherits System.Web.Services.Protocols.SoapHeader

            <System.Xml.Serialization.XmlText()> _
            Public UserName As String
        End Class

        <System.SerializableAttribute(), _
            System.ComponentModel.DesignerCategoryAttribute("code"), _
             System.Xml.Serialization.XmlTypeAttribute([Namespace]:="http://abc"), _
             System.Xml.Serialization.XmlRootAttribute([Namespace]:="http://abc", IsNullable:=False)> _
             Partial Public Class __SessionID
            Inherits System.Web.Services.Protocols.SoapHeader

            <System.Xml.Serialization.XmlText()> _
            Public SessionID As String
        End Class

    As you can see, UserName and SessionID are the values of "__UserName" and "__SessionID" respectively....

    I then declared two phantom soapHeader classes in the proxy class:

    Private _mySoapHeader As New __UserName()
            Private _mySoapHeader2 As New __SessionID()

            <System.Xml.Serialization.XmlAnyAttributeAttribute()> _
            Public Property xtraSoapHeader() As __UserName
                Get
                    Return Me._mySoapHeader
                End Get

                Set(ByVal value As __UserName)
                    Me._mySoapHeader = value
                End Set
            End Property
            <System.Xml.Serialization.XmlAnyAttributeAttribute()> _
            Public Property xtraSoapHeader2() As __SessionID
                Get
                    Return Me._mySoapHeader2
                End Get

                Set(ByVal value As __SessionID)
                    Me._mySoapHeader2 = value
                End Set
            End Property

    and then added the declaration above the webmethod of the proxy class that I need to serialize the soap header:

    <System.Web.Services.Protocols.SoapDocumentMethodAttribute("http://abc/blah", RequestNamespace:="http://abc", ResponseNamespace:="http://abc", Use:=System.Web.Services.Description.SoapBindingUse.Literal, ParameterStyle:=System.Web.Services.Protocols.SoapParameterStyle.Wrapped), _
            System.Web.Services.Protocols.SoapHeader("xtraSoapHeader"), _
            System.Web.Services.Protocols.SoapHeader("xtraSoapHeader2")> _
            Public Function blah

    Seeing double?  So am I! But it works... it only gives me the soapHeader I want!!

    <soap:Header>
                   <__UserName xmlns="http://abc/">xxxxxxxxx</__UserName>
                   <__SessionID xmlns="http://abc/">someValue</__SessionID>
      </soap:Header>

    I know it is not the best but I am using .NET 2.0 here (!) and I am running out of time for this project...so I don't care....please let me know if there is better wahy to achieve this.

    Thanks for reading this.

     


    --- WML ---
    • Marked as answer by WML-AUS Wednesday, October 13, 2010 9:13 AM
    Wednesday, October 13, 2010 9:12 AM
  • Hi

    I have gone through your code and its helpful, I would like to know , do you found any other altenative way or are you still following this same format,

    I am havinga scenario like, i need to pass the SOAP header in the same format as you have done, I am consuming a Seibel webservice..

    Thanks in advance

    Midhun Sunny

    Thursday, April 26, 2012 10:53 AM
  • I haven't touched this for a while and I haven't invested more time on this...I was so glad the thing works and have moved on...sorry can't give you more help.  BTW I don't know what a Seibal webservice is....:-(


    --- WML ---

    Thursday, April 26, 2012 11:38 PM
  • Hi,

    Thanks for your reply. :)

    I have done this.

    I have a doubt regarding the Webservice Please find the se below, In my response I am getting a sessionToken as response and I want to retrieve this to my application , how this can be done? (I am using a proxy class generated using wsdl.exe, the webservice is not developed in .Net)

    Request

    <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
      <soap:Header>
        <Header1 xmlns="http://siebel.com/webservices">
          <UsernameToken>uname</UsernameToken>
          <PasswordText>pass</PasswordText>
          <SessionType>Stateless</SessionType>
        </Header1>
      </soap:Header>
      <soap:Body>
         </soap:Body>
    </soap:Envelope>

    Response

    <SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
       <SOAP-ENV:Header>
          <siebel-header:SessionToken xmlns:siebel-header="">http://siebel.com/webservices">mB.982yqWeGqDBiwxJhY.-kDNeFzPYWQs92TJ9HDAzEMBCoWrpEJdXkL13FZkLDoDF89hnRC88kaXz2x6n1FpTAqJOaXZ.dnXgS5U3Ki7l3C92vnv.7w4MzgLk6lNEAWhbarX-5bCqCCEJyOXuUo2X8HONFga0hHAgkjXk3JKnxxgG7jtAQkASOiSfF06QoTBk4AWfdl9tm1d8PWobB9U7o1taM83vyMJM4yB9HJ6AvYEE039VO.7IdxkS8kdK9O0kSpOc.gZX6srSbEXZ2vKD3VH5zw.RB-</siebel-header:SessionToken">mB.982yqWeGqDBiwxJhY.-kDNeFzPYWQs92TJ9HDAzEMBCoWrpEJdXkL13FZkLDoDF89hnRC88kaXz2x6n1FpTAqJOaXZ.dnXgS5U3Ki7l3C92vnv.7w4MzgLk6lNEAWhbarX-5bCqCCEJyOXuUo2X8HONFga0hHAgkjXk3JKnxxgG7jtAQkASOiSfF06QoTBk4AWfdl9tm1d8PWobB9U7o1taM83vyMJM4yB9HJ6AvYEE039VO.7IdxkS8kdK9O0kSpOc.gZX6srSbEXZ2vKD3VH5zw.RB-</siebel-header:SessionToken>
       </SOAP-ENV:Header>
       <SOAP-ENV:Body>

    Thanks

    Midhun Sunny

    Friday, April 27, 2012 1:45 PM