How to add SOAP message headers using Rebex custom WCF Binding

0 votes
asked May 17 by Lukas Matyska (43,090 points)

(Note, this was originally asked at comment)

We got an Requirement for OpenUI , that we need to add the Header with credential and session Tokens attribute as part of Request , and parse the Header also after response.

SOAP REQUEST:

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:cus="http://siebel.com/CustomUI" xmlns:fin="http://www.siebel.com/xml/FindLotInfo">
    <soapenv:Header>
      <UsernameToken xmlns="http://siebel.com/webservices">Username</UsernameToken>
      <PasswordText xmlns="http://siebel.com/webservices">Password</PasswordText>
      <SessionType xmlns="http://siebel.com/webservices">Stateless</SessionType>
   </soapenv:Header>
   <soapenv:Body>
      <cus:ATLFindLotInfoProcess_Input>
         <fin:FindLotInfo>
            <fin:findLotInfoReqData>
           ..................
         </fin:FindLotInfo>
      </cus:ATLFindLotInfoProcess_Input>
   </soapenv:Body>
</soapenv:Envelope>

SOAP 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">y3dgzHgjMNDAroudyW3FdqDjRzjMJN.cHyU6rOlrsSVJvLrgcCEioOo29u502bo4HSnV3k9s4HhVNCuOP6oXaaUVSUbTaaxpVcNx2eks55Uvk0LCJzVvSBw5AkGUfs-b95OYNVHRGw7SGc49tOpjCRorlqabXXLmhqhnL1y8haqLLZDnZ5ORvQNWj8Q-p1oPG6LhYg1UQWeUf.-GwrR.WN7yLlr8v0kWjXTynLJao3ogQKJytT5ymzAnhJLIrYs8m18McEwFVv09i5K-B1-RvlXhq2t38g3vb3fbCmKyaFoJgy1jP0CcsA__</siebel-header:SessionToken>
   </SOAP-ENV:Header>
   <SOAP-ENV:Body>
      <ns:ATLFindLotInfoProcess_Output xmlns:ns="http://siebel.com/CustomUI">
         <FindLotInfoResponse xmlns="http://www.siebel.com/xml/FindLotInfoResponse">
            <findLotInfoReplyData>
             .......................
         </FindLotInfoResponse>
      </ns:ATLFindLotInfoProcess_Output>
   </SOAP-ENV:Body>
</SOAP-ENV:Envelope>
  • as per above sample Request /Resonse(using soaUI Tool) - I need to add the Header along with Request Body and I need to Parse the Header in Reponse as well.

    Please guide me on this.

  • am using the wcfRequestChannels.cs file which I took from Rebex sample http projects

where we adding header as below

    string action = message.Headers.Action;

    request.Method = "POST";
    request.Headers.Add("SOAPAction", '"' + action + '"');
    request.Headers.Add("Content-Type", "text/xml; charset=utf-8");
  • I need to add further information on this.

Regards
Raj

2 Answers

0 votes
answered May 18 by Lukas Matyska (43,090 points)
 
Best answer

I have uploaded new version of RebexWcfBinding with support for custom SOAP headers.

It is available at here.

It introduces new WcfMessageObserver class, which can be used like this:

    var binding = new Rebex.Samples.WcfBinding();
    // configure RequestCreator if necessary
    // binding.RequestCreator.Settings...

    // create service
    var client = new DemoWebServiceSoapClient(binding,
        new EndpointAddress("http://test.rebex.net/demowebservice.asmx"));

    // attach observer for next service call(s)
    using (var observer = new Rebex.Samples.WcfMessageObserver(binding))
    {
        // add some custom headers to outgoing SOAP message(s)
        observer.OutgoingHeaders.Add(new Rebex.Samples.WcfMessageHeader("A", "NS", "Temp1"));
        observer.OutgoingHeaders.Add(new Rebex.Samples.WcfMessageHeader("B", "NS", "Temp2"));

        // call the service
        var response = client.HelloWorld();

        // read SOAP headers of the most recent response
        foreach (var h in observer.IncomingHeaders)
        {
            // h.Name, h.Value, ...
        }
    }

It is also possible to create own IWcfMessageObserver implementation and attach it to WcfBinding.MessageObservers manually.

0 votes
answered May 17 by Lukas Matyska (43,090 points)

The request.Headers.Add() method adds HTTP headers (not SOAP message headers).

To add SOAP message headers, just simply add them to message.Headers collection after line 'message.Headers.Clear();' like this:

message.Headers.Clear();
message.Headers.Add(MessageHeader.CreateHeader("UsernameToken", "http://siebel.com/webservices", "a user name"));
message.Headers.Add(MessageHeader.CreateHeader("PasswordText", "http://siebel.com/webservices", "a password"));
message.Headers.Add(MessageHeader.CreateHeader("SessionType", "http://siebel.com/webservices", "Stateless"));

To read them, just read from responseMessage.Headers collection.

commented Jun 12 by Lukas Matyska (43,090 points)
Since the comment is not related to the original question. I have created new question here: http://forum.rebex.net/8598/unable-to-resolve-hostname-on-wince

You will find my answer there.
commented 5 days ago by RajaK (110 points)
hi Lukas,
 I was trying to create    - System.ServiceModel.Channels.MessageEncoder implementation.
to contruct the message header as below, seems the WcfchannelFactory.cs already referring the default  - encoder.
request you to kindly help to create as below and parse the response

Request:
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:cus="http://siebel.com/CustomUI" xmlns:pur="http://www.siebel.com/xml/PurchaseProduct">
   <soapenv:Header>
      <UsernameToken xmlns="http://siebel.com/webservices">eaiuser</UsernameToken>
      <PasswordText xmlns="http://siebel.com/webservices">Ea!us3r456</PasswordText>
      <SessionType xmlns="http://siebel.com/webservices">Stateless</SessionType>
   </soapenv:Header>
   <soapenv:Body>
......    
   </soapenv:Body>
</soapenv: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">7HM14u8cg-xBqeYWuPQU9uc2eo9Su8EEzueu-WwsgEltfj89QBBQQ2I9S5Dp.dJmSxPs7uXjTwWoQKPgN-s1ChDFnMuTrL7lhuUnIT4UHDFuFuPgPrL.jCbSIpiMWWCH2v8uRHYlGJNmKF0290Y3ssZvnxlaR4ZgSCS7GC0JZR7s.VDo74MH1O-IMheWYvLJhgyh7PjUZxRTSkQpafSfmKyZLSnEa2Vz5AZ47g2ikOtoGwmMCBj4nV4H2ijzRNQ2KBGXJsxqueHn5Y3pffgym0wObelUly.rVVsfQdwaSuYDEMbleN2i0w__</siebel-header:SessionToken>
   </SOAP-ENV:Header>
   <SOAP-ENV:Body>
      <ns:PurchasePermit_Output xmlns:ns="http://siebel.com/CustomUI">
         <PurchaseProductResponse xmlns="http://www.siebel.com/xml/PurchaseProductResponse">
            <replyData>
               <sessionData>
                  <sessionId>rrr5555</sessionId>
                  <equipmentId/>
               </sessionData>
               <responseDate>06/18/2018</responseDate>
               <statusCode>0300</statusCode>
               <errorInfo>Patron doesn’t have permit.</errorInfo>
               <listOfPaymentAuthorization>
                  <authorizationtDef>
                     <bankAuthorizationCode/>
                     <requestAmount/>
                     <name/>
                     <attrib01/>
                     <attrib02/>
                     <attrib04/>
                  </authorizationtDef>
               </listOfPaymentAuthorization>
            </replyData>
         </PurchaseProductResponse>
      </ns:PurchasePermit_Output>
   </SOAP-ENV:Body>
</SOAP-ENV:Envelope>
commented 4 days ago by Lukas Matyska (43,090 points)
I have already written that namespace has no functional effect for SOAP capabilities.

If your server requires <soapenv:Envelope ...> instead of <soap:Envelope ...> its the imperfection of the server not the client.

I am sorry, but this request is out of Rebex support. We will not implement this.

If you have problems to implement own MessageEncoder, you can try to rewrite the produced XML. In WcfRequestChannel locate _encoder.WriteMessage call and use your stream instead HTTP request stream. Then modify your stream as you want. Finally copy your stream into HTTP request stream.

The code skeleton looks like this:

            _encoder.WriteMessage(message, yourStream);

            // modify yourStream as you want
            // e.g. read XmlDocument from yourStream and perform namespace changes
            // save modified XmlDocument into modifiedStream

            using (var requestStream = request.GetRequestStream())
            {
                // copy modifiedStream into requestStream
            }
commented 4 days ago by RajaK (110 points)
edited 4 days ago by RajaK
Thank You Lukas, I will ask server team to look in this  - I mean while I will check to implement the device.
commented 4 days ago by RajaK (110 points)
edited 4 days ago by RajaK
Thank You Lukas, I will ask server team to look in this  - I mean while I will check to implement the device.
...