ASMX Web Services with SOAP Extension

Posted by digitall on Stack Overflow See other posts from Stack Overflow or by digitall
Published on 2010-04-25T05:34:18Z Indexed on 2010/04/25 5:43 UTC
Read the original article Hit count: 567

Filed under:
|

I am in the process of setting up a web service for an external client to connect to my client's application and update some information. I went the ASMX route (the rest of the application runs on WCF) because I knew the external client could be very difficult to deal with and I was trying to keep everything as simple as possible. They also aren't a .Net shop which makes things worse. After getting the service setup for them I provided the ASMX URL for them to see how to format the SOAP headers/message content. They have since come back and told me their tool is unable to send them in the format required by .Net and I can either come up with a different way to accept messages or we have to go with FTP.

Based on this I have been researching how to intercept their message, reformat it the way my service requires it (which means adding two lines), and then let it process. This path led me to SOAP Extensions which I have been trying to work with but can't seem to figure out. When I have my sample application call the web service from the generated code Add Web Reference provides everything works great until I add in my extension. All it currently does is override ChainStream setting an internal stream equal to the one being passed in and returning a new stream, like this:

private Stream newStream = null;
private Stream oldStream = null;

public override Stream ChainStream(Stream stream)
{
    this.oldStream = stream;
    this.newStream = new MemoryStream();
    return newStream;
}

I also override ProcessMessage and in it take the contents of oldStream and set newStream equal to that and then write to a different stream with an XmlWriter. I take that new stream and using a StreamReader read it into a string, with the end goal being manipulating it here and setting newStream (which is being used by ChainStream) equal to the contents of this. Here is that piece:

    public override void ProcessMessage(SoapMessage message)
{
    switch (message.Stage)
    {
        case SoapMessageStage.BeforeDeserialize:
            this.Process();
            break;

        default: break;
    }
}

private void Process()
{
    this.newStream.Position = 0L;
    XmlTextReader reader = new XmlTextReader(this.oldStream);
    MemoryStream outStream = new MemoryStream();
    using (XmlWriter writer = XmlWriter.Create(outStream))
    {
        do { writer.WriteNode(reader, true); } while (reader.Read());
        writer.Flush();
    }
    outStream.Seek(0, SeekOrigin.Begin);
    StreamReader streamReader = new StreamReader(outStream);
    string message = streamReader.ReadToEnd();
    newStream = outStream;
    newStream.Seek(0, SeekOrigin.Begin);
    streamReader.Close();

}

By running this, which seems to me like it would be fine, my test application gets a 400 Bad Request back from the service. If I either don't use the extension or I don't do anything in ProcessMessage everything seems fine. Any suggestions to this?

As a side note, once I get this working with the generated code from the WSDL I will be moving to a WebRequest to try sending the message to the service. Currently that bombs out with a 415 Unsupported Media Type response. I'm trying to keep this post to one question but if anyone has any tips with using a WebRequest to connect to an ASMX service it would be much appreciated!

© Stack Overflow or respective owner

Related posts about asmx

Related posts about soap