Question

I've created an WebService proxy class based on a WSDL (in my Visual Studio 2010 .NET solution).

Now what I need is, that the soap header of my request to the remote web service have a specific format, imagine something with two or three fields is not very relevant.

So my solution was, I edited the code generated by Visual Studio and commented out the method where i needed that custom soap header.

Next, because the web service class is marked as partial, I created safe code (that cannot be touched by the generator) in a class with the same name of the generated one (so it's the same class) and declared there the method commented out previously.

I declared it like this:

//this is the generated code file
public partial class Invoices: InvoicesWS.invoices
{ 
    //[System.Web.Services.Protocols.SoapDocumentMethodAttribute( ...
    //public RegisterInvoiceResponseType RegisterInvoice(RegisterInvoiceType ...) 
    //{ ... }  
}

//this is the class I created else where in my project
public partial class Invoices: InvoicesWS.invoices
{
    public SecureSoapHeader Security { get; set; }

    [SoapHeader("Security", Direction = SoapHeaderDirection.In)]          
    [System.Web.Services.Protocols.SoapDocumentMethodAttribute(
         "http://someurl.pt/invoices/RegisterInvoice", 
         Use = System.Web.Services.Description.SoapBindingUse.Literal, 
         ParameterStyle = System.Web.Services.Protocols.SoapParameterStyle.Bare),
         TraceExtension()]
    public RegisterInvoiceResponseType RegisterInvoice(RegisterInvoiceType RegisterInvoiceElem) 
    {
        object[] results = 
            this.Invoke("RegisterInvoice", new object[] {RegisterInvoiceElem});

        return ((RegisterInvoiceResponseType)(results[0]));
    }
}

So, to make my proxy class send a custom header I did this. But every time I remember to update the web reference, I'll have to manually comment out the method above that is being generated by the Visual Studio tool, to avoid conflicts due to having to methods with the same signature.

Is there a better way, or best practice to address this situation?

Please do not advise me to do it with WCF, I know the solution for that, but correctly this is the code that has been working and changing it at this time is not a possibility.

Thanks.

Was it helpful?

Solution

You can achieve it with SoapExtension. You can create class that implements SoapExtension, and register it in web.config.

Sample of soap extension:

public class SecureSoapExtension : SoapExtension
{

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

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

    public override void Initialize(object initializer)
    {

    }

    public override void ProcessMessage(SoapMessage message)
    {
        // just for out requests
        if (message.Stage == SoapMessageStage.BeforeSerialize)
        {
            // add needed soap header here
            message.Headers.Add(new SecureSoapHeader());
        }
    }
}

And register in web.config to apply to all web services:

  <system.web>
      <webServices>
          <soapExtensionTypes>
              <add type="MyTestMvcApplication.SecureSoapExtension, MyTestMvcApplication, Version=1.0.0.0, Culture=neutral"></add>
          </soapExtensionTypes>
      </webServices>
  </system.web>

Important note: If you are calling your Web Service from an external project, let's say, you have a Class Library where you program all your Proxy handling logic. You must add this to your calling project web.config/app.config too, otherwise it will not work:

  <system.web>
      <webServices>
          <soapExtensionTypes>
              <add type="MyTestMvcApplication.SecureSoapExtension, MyTestMvcApplication, Version=1.0.0.0, Culture=neutral"></add>
          </soapExtensionTypes>
      </webServices>
  </system.web>

What kind of makes sense, since it's an Web Service extension it's let up to you "final caller" of the proxy, to decide whether to extend or not the web service request.

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