Question

I'm trying to consume an Axis web service with a .NET client and I'm having some trouble setting up the WSE configuration to work with it. I know that WSE 3.0 is an outdated technology, but I'm stuck with a VS2005 and .NET 2.0 environment, so I'll have to work with this.

Currently I've created a new ASP.NET Website application and enabled WSE on it. It generages a bunch of sections like the WS:Addressing and WS:Timestamp sections from it that the server cannot handle and I'm looking to remove them. I couldn't find a config setting to do it, so after some searching on SO, I've started working with SoapExtensions to intercept the message and remove the sections manually.

My problem currently seems to be that the code in the SoapExtensions isn't getting executed at all. Here's my web.config -

<configuration>
  <configSections>
    <section name="microsoft.web.services3" type="Microsoft.Web.Services3.Configuration.WebServicesConfiguration, Microsoft.Web.Services3, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" />
  </configSections>
  <appSettings>
    <add key="WebSvc.SecureService" value="<Trimmed>" />
  </appSettings>
  <connectionStrings />
  <system.web>
    <compilation debug="true">
      <assemblies>
        <add assembly="Microsoft.Web.Services3, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" />
      </assemblies>
    </compilation>
    <authentication mode="Windows" />
    <webServices>
      <soapExtensionImporterTypes>
        <add type="Microsoft.Web.Services3.Description.WseExtensionImporter, Microsoft.Web.Services3, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" />
      </soapExtensionImporterTypes>
      <soapServerProtocolFactory type="Microsoft.Web.Services3.WseProtocolFactory, Microsoft.Web.Services3, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" />
    </webServices>
  </system.web>
  <microsoft.web.services3>
    <security>
      <x509 verifyTrust="false" />
      <defaultTtlInSeconds value="0" />
      <timeToleranceInSeconds value="0" />
    </security>
    <diagnostics>
      <trace enabled="true" input="InputTrace.webinfo" output="OutputTrace.webinfo" />
    </diagnostics>
    <policy fileName="wse3policyCache.config" />
  </microsoft.web.services3>
</configuration>

And my web service method -

[WebMethod]
[TestApplication.TraceExtensionAttribute]
public void SendTestMessage()
{
    WebSvc.B2BSecureServiceServiceWse svcClient = new WebSvc.B2BSecureServiceServiceWse();
    svcClient.SetPolicy("Policy1");
    WebSvc.B2BRequest request = new WebSvc.B2BRequest();
    WebSvc.B2BRequestHeader WebSvc= new WebSvc.B2BRequestHeader();
    // Set Request header properties
    request.header = requestHeader;
    request.msgPayload = ""; // Text removed

    try
    {
        WebSvc.Response response = svcClient.processRequest(request);
    }
    catch (Exception ex)
    { 

    }
}

And here's my SoapExtension Class -

public class Snoop : SoapExtension
{
    Stream oldStream;
    Stream newStream;
    string filename;

    // Save the Stream representing the SOAP request or SOAP response into
    // a local memory buffer.
    public override Stream ChainStream(Stream stream)
    {
        oldStream = stream;
        newStream = new MemoryStream();
        return newStream;
    }

    // When the SOAP extension is accessed for the first time, the XML Web
    // service method it is applied to is accessed to store the file
    // name passed in, using the corresponding SoapExtensionAttribute.  
    public override object GetInitializer(LogicalMethodInfo methodInfo, SoapExtensionAttribute attribute)
    {
        return ((TraceExtensionAttribute)attribute).Filename;
    }
    // The SOAP extension was configured to run using a configuration file
    // instead of an attribute applied to a specific XML Web service
    // method.
    public override object GetInitializer(Type WebServiceType)
    {
        // Return a file name to log the trace information to, based on the
        // type.
        return "C:\\" + WebServiceType.FullName + ".log";
    }
    // Receive the file name stored by GetInitializer and store it in a
    // member variable for this specific instance.
    public override void Initialize(object initializer)
    {
        filename = (string)initializer;
    }
    //  If the SoapMessageStage is such that the SoapRequest or
    //  SoapResponse is still in the SOAP format to be sent or received,
    //  save it out to a file.
    public override void ProcessMessage(SoapMessage message)
    {
        switch (message.Stage)
        {
            case SoapMessageStage.BeforeSerialize:
                break;
            case SoapMessageStage.AfterSerialize:
                WriteOutput(message);
                break;
            case SoapMessageStage.BeforeDeserialize:
                WriteInput(message);
                break;
            case SoapMessageStage.AfterDeserialize:
                break;
        }
    }

    public void WriteOutput(SoapMessage message)
    {
        newStream.Position = 0;
        FileStream fs = new FileStream(filename, FileMode.Append,
            FileAccess.Write);
        StreamWriter w = new StreamWriter(fs);

        string soapString = (message is SoapServerMessage) ? "SoapResponse" : "SoapRequest";
        w.WriteLine("-----" + soapString + " at " + DateTime.Now);
        w.Flush();
        Copy(newStream, fs);
        w.Close();
        newStream.Position = 0;
        Copy(newStream, oldStream);
    }

    public void WriteInput(SoapMessage message)
    {
        Copy(oldStream, newStream);
        FileStream fs = new FileStream(filename, FileMode.Append,
            FileAccess.Write);
        StreamWriter w = new StreamWriter(fs);

        string soapString = (message is SoapServerMessage) ?
            "SoapRequest" : "SoapResponse";
        w.WriteLine("-----" + soapString +
            " at " + DateTime.Now);
        w.Flush();
        newStream.Position = 0;
        Copy(newStream, fs);
        w.Close();
        newStream.Position = 0;
    }

    void Copy(Stream from, Stream to)
    {
        TextReader reader = new StreamReader(from);
        TextWriter writer = new StreamWriter(to);
        writer.WriteLine(reader.ReadToEnd());
        writer.Flush();
    }

}
// Create a SoapExtensionAttribute for the SOAP Extension that can be
// applied to an XML Web service method.
[AttributeUsage(AttributeTargets.Method)]
public class TraceExtensionAttribute : SoapExtensionAttribute
{

    private string filename = "c:\\log.txt";
    private int priority;

    public override Type ExtensionType
    {
        get { return typeof(Snoop); }
    }

    public override int Priority
    {
        get { return priority; }
        set { priority = value; }
    }

    public string Filename
    {
        get
        {
            return filename;
        }
        set
        {
            filename = value;
        }
    }
}

I'm guessing I'm doing something wrong while trying to assign the SoapExtension to that method call, so any help is much appreciated!

Was it helpful?

Solution

For anyone who comes across this problem, here's how I've solved it using SoapFilters. Here's the process from MSDN - http://msdn.microsoft.com/en-us/library/aa528788.aspx

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top