=

desalasworks presents:

a selection of works by steven de salas

How to obtain SOAP Request body in C# Web Services

Microsoft left something out when designing web services, fortunately there is a nifty way to obtain the original SOAP request within a C# web service.

I’ve written an article on this topic before. Its possible to obtain the SOAP request body for logging purposes by using SoapExtensions. And that’s all well and good if you want to log the traffic between your SOAP web service and the outside world. But what if you want to change the behaviour of your web services based on the input that comes in?

Say for example, you want to validate your SOAP request against an XML schema to enforce additional validation than what comes out of the box with .NET by default.

The process is quite simple, you need to find the Request object and load the contents of little known property called ‘InputStream‘. You can mine the contents of the SOAP request and load them into an XML document easily as follows:

Creating an ‘Echo’ Soap Request

Using this technique we can create a simple Web Service that performs a simple ‘Echo’ of whatever you send into it. See the following code:

using System;
using System.Collections.Generic;
using System.Web;
using System.Xml;
using System.IO;
using System.Text;
using System.Web.Services;
using System.Web.Services.Protocols;

namespace SoapRequestEcho
{
  [WebService(
  Namespace = "http://soap.request.echo.com/",
  Name = "SoapRequestEcho")]
  public class EchoWebService : WebService
  {
    [WebMethod(Description = "Echo Soap Request")]
    public XmlDocument EchoSoapRequest(int input)
    {
      // Initialize soap request XML
      XmlDocument xmlSoapRequest = new XmlDocument();
    
      // Get raw request body
      using (Stream receiveStream = HttpContext.Current.Request.InputStream)
      {
        // Move to begining of input stream and read
        receiveStream.Position = 0;
        using (StreamReader readStream = 
                               new StreamReader(receiveStream, Encoding.UTF8))
        {
          // Load into XML document
          xmlSoapRequest.Load(readStream);
        }
      }
      // Return
      return xmlSoapRequest;
    }
  }
}

Testing our Soap Request

We can quickly test our SOAP request and check that we are processing whatever XML is being sent in and its coming out the other side untouched.

Next Steps: Performing Schema Validation

Now you can do what you want with your xmlSoapRequest object. It’ll contain exactly the same request as was sent into SOAP in the first place.

If you are after schema validation.The next step is to populate the xmlSoapRequest.Schemas property and then fire off theĀ xmlSoapRequest.Validate() method.

Piece of cake.

Comments

2 comments

  1. John Saunders says:

    Thanks for a good article.

    I would note, however, that Microsoft didn’t leave anything out. All of these features are available from SoapExtensions. I have used them in the past both for logging and for schema validation (both of the incoming and outgoing messages).

    In addition, SoapExtensions may be used to modify the XML before it is parsed, and I believe I have seen others use them to modify the parameters to be sent to the web method.

    This is a very powerful set of features that you cannot get by modifying Request.InputStream.

    I will note that SoapExtensions can be tricky to get right. I recommend that anyone wanting to create one should start with the example on MSDN, make it work, then refactor it to become what you need (frequently testing to make sure it still works).

  2. Angelo says:

    Hi,

    Use Soap Extensions to log the outgoing and incoming XML.

    You must add the SoapExtension attribute to the proxy class of the Web Service

    Look at this site, that explain how presicion as using SoapExtension,
    hope will be helpful.

    http://www.systemdeveloper.info/2013/11/trace-soap-requestresponse-xml-with.html