Hitesh
Hitesh

Reputation: 137

ws-addressing in soap request programatically

I am trying to use a third party soap based web service into my project. While sending manual soap requests via soap-ui, it is getting timed out but when i am adding check on enable ws-addressing through soap-ui, it works smoothly.

Now the issue is, i am unable to integrate this into my existing app as ws-addressing isn't enabled in code anywhere. Any suggestion on how this can be done?

Codebase is in c#

Upvotes: 1

Views: 5936

Answers (1)

Konrad Kokosa
Konrad Kokosa

Reputation: 16878

What makes a difference in SoapUI with "Enable/Disable WS-A addresing" checked or not is a <wsa:Action> tag added by default to the SOAP header.

If you use WCF, you can add WS-Addressing headers like specified in How do I use WS-Addressing in WCF and set the wsa:replyto header? and I would start from adding Action header.

EDIT: Knowing that SoapExtension class is used, here is a complete example of adding WS-Addressing Action header to the request sent by client:

public class WebServiceSOAPExtension : SoapExtension
{
    private Stream inwardStream;
    private Stream outwardStream;

    public override Stream ChainStream(Stream stream)
    {
        outwardStream = stream;
        inwardStream = new MemoryStream();
        return inwardStream;
    }

    public override object GetInitializer(Type serviceType)
    {
        return null;
    }

    public override object GetInitializer(LogicalMethodInfo methodInfo, SoapExtensionAttribute attribute)
    {
        return null;
    }

    public override void Initialize(object initializer)
    {
        return;
    }

    public override void ProcessMessage(System.Web.Services.Protocols.SoapMessage message)
    {
        switch (message.Stage)
        {
            case SoapMessageStage.BeforeSerialize:
                break;
            case SoapMessageStage.AfterDeserialize:
                break;
            case SoapMessageStage.BeforeDeserialize:
                RewriteResponse();
                break;
            case SoapMessageStage.AfterSerialize:
                RewriteRequest();
                break;
        }
    }

    private void RewriteResponse()
    {
        string message;
        var streamReader = new StreamReader(outwardStream);
        var streamWriter = new StreamWriter(inwardStream);
        message = streamReader.ReadToEnd();
        streamWriter.Write(message);
        streamWriter.Flush();
        inwardStream.Position = 0;
    }

    private void RewriteRequest()
    {
        string message;
        XmlDocument xmlDoc = new XmlDocument();
        inwardStream.Position = 0;
        var streamReader = new StreamReader(inwardStream);
        var streamWriter = new StreamWriter(outwardStream);
        message = streamReader.ReadToEnd();

        xmlDoc.LoadXml(message);
        var bodyNode = xmlDoc.GetElementsByTagName("Body", "http://www.w3.org/2003/05/soap-envelope/")[0];
        var headerNode = xmlDoc.CreateElement("s", "Header", "http://www.w3.org/2003/05/soap-envelope/");
        var actionNode = xmlDoc.CreateElement("wsa", "Action", "http://www.w3.org/2004/12/addressing");
        actionNode.InnerText = "http://sampleserver.example/Action";
        headerNode.AppendChild(actionNode);
        bodyNode.ParentNode.InsertBefore(headerNode, bodyNode);

        message = xmlDoc.InnerXml;
        streamWriter.Write(message);
        streamWriter.Flush();
    }
}

This class must be registered in client's web application:

<webServices>
  <soapExtensionTypes>
    <add type="WebApplication1.WebServiceSOAPExtension, WebApplication1" priority="1" group="Low" />
  </soapExtensionTypes>
</webServices>

Upvotes: 1

Related Questions