Link to home
Start Free TrialLog in
Avatar of townsma
townsmaFlag for Indonesia

asked on

Problems making an XML Soap Header

I need to access a webservice developed by another company.  This webservice requires a correctly formatted Header for authentication.  A sample that they provided is attached.

I have spent hours researchign how to make soap headers, and I am almost there, however the soap header I create has an extra layer in it.  Which is making it invalid.  I have tried everything to "not" have this extra layer, but I cannot work it out.  

Can someone please put me out of my misery.

Below is the code I use to create the header.  This appears to be correct, but this issues is the XML we are sending.

using (new OperationContextScope(_svc.InnerChannel))
                {
                    var doc = new XmlDocument();

                    var rootNode = doc.CreateElement("HTNGHeader");

                    doc.AppendChild(rootNode);

                    var from = doc.CreateElement("From");

                    var systemId = doc.CreateElement("systemId");
                    var systemIdText = doc.CreateTextNode(_connector.SystemId);

                    systemId.AppendChild(systemIdText);
                    from.AppendChild(systemId);

                    var credential = doc.CreateElement("Credential");
                    var userName = doc.CreateElement("userName");
                    var password = doc.CreateElement("password");
                    var usernameText = doc.CreateTextNode(_connector.UserId);
                    var passwordText = doc.CreateTextNode(_connector.Password);
                    userName.AppendChild(usernameText);
                    password.AppendChild(passwordText);
                    credential.AppendChild(userName);
                    credential.AppendChild(password);
                    from.AppendChild(credential);

                    rootNode.AppendChild(from);

                    var to = doc.CreateElement("To");
                    var systemIdR = doc.CreateElement("systemId");
                    var systemIdRText = doc.CreateTextNode("REVINATE");
                    systemIdR.AppendChild(systemIdRText);
                    to.AppendChild(systemIdR);

                    var address = doc.CreateElement("address");
                    var addressText = doc.CreateTextNode(_connector.Url);
                    address.AppendChild(addressText);
                    to.AppendChild(address);

                    rootNode.AppendChild(to);

                    var timestamp = doc.CreateElement("timestamp");
                    var timestampText = doc.CreateTextNode("2015-09-09T12:00:00-07:00");
                    timestamp.AppendChild(timestampText);
                    rootNode.AppendChild(timestamp);

                    var token = doc.CreateElement("echoToken");
                    var tokenText = doc.CreateTextNode(new Guid().ToString());
                    token.AppendChild(tokenText);
                    rootNode.AppendChild(token);

                    var transactionId = doc.CreateElement("transactionId");
                    var transText = doc.CreateTextNode("123456");
                    transactionId.AppendChild(transText);
                    rootNode.AppendChild(transactionId);

                    var action = doc.CreateElement("action");
                    var actionText = doc.CreateTextNode("RESPONSE");
                    action.AppendChild(actionText);
                    rootNode.AppendChild(action);

                    var aMessageHeader = MessageHeader.CreateHeader("HTNGHeader", "http://htng.org/1.1/Header/", doc.InnerXml);
                    OperationContext.Current.OutgoingMessageHeaders.Add(aMessageHeader);

                }

Open in new window


The header should look like

<HTNGHeader xmlns="http://htng.org/1.1/Header/">
  <From>
    <systemId>systemId</systemId>
    <Credential>
      <userName>userName</userName>
      <password>password</password>
    </Credential>
  </From>
  <To>
    <systemId>RENIVATE</systemId>
    <address>https://mercer.revinate.com/interface/htng/ariandreservationpush</address>
  </To>
  <timestamp>2015-09-09T12:00:00-07:00</timestamp>
  <echoToken>123456789</echoToken>
  <transactionId>55678</transactionId>
  <action>RESPONSE</action>
</HTNGHeader>

Open in new window


But what I am actually getting is.

<HTNGHeader xmlns="http://htng.org/1.1/Header/">
<HTNGHeader>
  <From>
    <systemId>systemId</systemId>
    <Credential>
      <userName>userName</userName>
      <password>password</password>
    </Credential>
  </From>
  <To>
    <systemId>RENIVATE</systemId>
    <address>https://mercer.revinate.com/interface/htng/ariandreservationpush</address>
  </To>
  <timestamp>2015-09-09T12:00:00-07:00</timestamp>
  <echoToken>123456789</echoToken>
  <transactionId>55678</transactionId>
  <action>RESPONSE</action>
</HTNGHeader>
</HTNGHeader>

Open in new window


As you can see there is the extra layer of the root element.
Avatar of Mlanda T
Mlanda T
Flag of South Africa image

Try this:
using (new OperationContextScope(_svc.InnerChannel))
{
    var doc = new XmlDocument();

    var rootNode = doc.CreateElement("HTNGHeader", "http://htng.org/1.1/Header/");

    doc.AppendChild(rootNode);

    var from = doc.CreateElement("From");

    var systemId = doc.CreateElement("systemId");
    var systemIdText = doc.CreateTextNode(_connector.SystemId);

    systemId.AppendChild(systemIdText);
    from.AppendChild(systemId);

    var credential = doc.CreateElement("Credential");
    var userName = doc.CreateElement("userName");
    var password = doc.CreateElement("password");
    var usernameText = doc.CreateTextNode(_connector.UserId);
    var passwordText = doc.CreateTextNode(_connector.Password);
    userName.AppendChild(usernameText);
    password.AppendChild(passwordText);
    credential.AppendChild(userName);
    credential.AppendChild(password);
    from.AppendChild(credential);

    rootNode.AppendChild(from);

    var to = doc.CreateElement("To");
    var systemIdR = doc.CreateElement("systemId");
    var systemIdRText = doc.CreateTextNode("REVINATE");
    systemIdR.AppendChild(systemIdRText);
    to.AppendChild(systemIdR);

    var address = doc.CreateElement("address");
    var addressText = doc.CreateTextNode(_connector.Url);
    address.AppendChild(addressText);
    to.AppendChild(address);

    rootNode.AppendChild(to);

    var timestamp = doc.CreateElement("timestamp");
    var timestampText = doc.CreateTextNode("2015-09-09T12:00:00-07:00");
    timestamp.AppendChild(timestampText);
    rootNode.AppendChild(timestamp);

    var token = doc.CreateElement("echoToken");
    var tokenText = doc.CreateTextNode(new Guid().ToString());
    token.AppendChild(tokenText);
    rootNode.AppendChild(token);

    var transactionId = doc.CreateElement("transactionId");
    var transText = doc.CreateTextNode("123456");
    transactionId.AppendChild(transText);
    rootNode.AppendChild(transactionId);

    var action = doc.CreateElement("action");
    var actionText = doc.CreateTextNode("RESPONSE");
    action.AppendChild(actionText);
    rootNode.AppendChild(action);

	//var aMessageHeader = MessageHeader.CreateHeader("HTNGHeader", "http://htng.org/1.1/Header/", doc.InnerXml);
	//OperationContext.Current.OutgoingMessageHeaders.Add(aMessageHeader);

}

Open in new window

ASKER CERTIFIED SOLUTION
Avatar of mccarl
mccarl
Flag of Australia image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Or using built-in serialization:

namespace ConsoleCS
{
    using System;
    using System.Xml.Serialization;

    public enum Action { RESPONSE, REQUEST }

    public class Credential
    {
        public string UserName { get; set; }
        public string Password { get; set; }
    }

    public class From
    {
        public string SystemID { get; set; }
        public Credential Credential { get; set; }
    }

    public class To
    {
        public string SystemID { get; set; }
        public string Address { get; set; }
    }

    public class HTNGHeader
    {
        public From From { get; set; }
        public To To { get; set; }
        public DateTime TimeStamp { get; set; }
        public string EchoToken { get; set; }
        public int TransactionID { get; set; }
        public Action Action { get; set; }
    }

    class Program
    {

        static void Main(string[] args)
        {
            XmlSerializerNamespaces namespaces = new XmlSerializerNamespaces();
            namespaces.Add("ns", "http://contoso.com");
            XmlSerializer xser = new XmlSerializer(typeof(HTNGHeader));
            HTNGHeader obj = new HTNGHeader();
            obj.Action = Action.RESPONSE;
            obj.EchoToken = "EchoToken";
            obj.TimeStamp = DateTime.Now;
            obj.TransactionID = 123456789;
            obj.From = new From() { SystemID = "SystemID", Credential = new Credential() { UserName = "UserName", Password = "Password" } };
            obj.To = new To() { SystemID = "SystemID", Address = "http://contoso.com" };
            xser.Serialize(Console.Out, obj, namespaces);

            Console.WriteLine("Done.");
            Console.ReadLine();
        }
    }
}

Open in new window

Avatar of townsma

ASKER

The simplest things are sometimes the hardest to find.

Many thanks
You're welcome!