Search code examples
c#soapcustom-attributessoap-extension

Passing information to the object on which a SoapExtensionAttribute is applied on


In my application, I'm calling a web service and by using SoapExtension and SoapExtensionAttribute I can intercept the incoming and outgoing SOAP messages for logging purposes. I used the example in http://msdn.microsoft.com/en-us/magazine/cc164007.aspx as input. But now I want to go one step further. I have a Windows client that calls my class (in a separate project) and the class then calls the web service. I can now intercept the SOAP messages, but instead of directly logging them to a file, I want to pass those messages back to my class that is calling the web service and also back to the client that is calling my class. These are the code changes I have made so far:

        private String ExtractFromStream(Stream target)
    {
        if (target != null)
            return (new StreamReader(target)).ReadToEnd();

        return "";
    }

    public void WriteOutput(SoapMessage message)
    {
        newStream.Position = 0;
        string soapOutput = ExtractFromStream(newStream);

        newStream.Position = 0;
        Copy(newStream, oldStream);
    }

    public void WriteInput(SoapMessage message)
    {
        Copy(oldStream, newStream);

        newStream.Position = 0;
        string soapInput= ExtractFromStream(newStream);
        newStream.Position = 0;
    }

I now want to pass the soapInput and soapOutput back to the class that holds the method that this attribute is applied on. Any clues on how I should do that?


Solution

  • For anyone that happens to pass by, here is the solution:

    The SoapMessage object does not contain any information about my client. However, I can cast this object to a SoapClientMessage object and then I will have access to my web service. If I now add a method to this webservice (by creating a new public partial class) I can access its properties and methods like this (purely an example!):

     private String ExtractFromStream(Stream target)
        {
            if (target != null)
                return (new StreamReader(target)).ReadToEnd();
    
            return "";
        }
    
    
    
        public void WriteOutput(SoapMessage message)
        {
            newStream.Position = 0;
    
            string soapOutput = ExtractFromStream(newStream);
            SoapClientMessage soapClient = (SoapClientMessage)message;
            WebServiceClass webservice = (WebServiceClass)soapClient.Client;
            webservice.MyMethod(soapOutput); //Use your own method here!
    
    
            newStream.Position = 0;
            Copy(newStream, oldStream);
        }
    
        public void WriteInput(SoapMessage message)
        {
            Copy(oldStream, newStream);           
            newStream.Position = 0;
    
            string soapInput= ExtractFromStream(newStream);
            SoapClientMessage soapClient = (SoapClientMessage)message;
            WebServiceClass webservice = (WebServiceClass)soapClient.Client;
            webservice.MyMethod(soapInput);
            newStream.Position = 0;
        }
    

    You can add methods (like the MyMethod in this example) to your WebServiceClass by creating a new public partial class and adding methods, properties and anything you like to it.