How To Pass Soap Header When WSDL Doesn't Define It?

后端 未结 4 1679
走了就别回头了
走了就别回头了 2020-12-19 19:09

I have a web service that I am calling and their published WSDL doesn\'t actually define much of the service, 3/4 of it you have to manually build afterwards.

The pr

相关标签:
4条回答
  • 2020-12-19 19:33

    You might want to see Adding implicit SOAP headers to C# on AdSense API Forum (archived) for something similar; it appears to be doable, but a lot of work... or you could build the entire request manually (even worse...).

    0 讨论(0)
  • 2020-12-19 19:44

    If you need fine grain control over how the soap header xml gets rendered (happens when interfacing with a webservice written with java), you can always override all rendering by implementing IXmlSerializable

    [XmlRoot("customHeader", Namespace = "http://somecompany.com/webservices/security/2012/topSecret")]
    public class customHeader: SoapHeader, IXmlSerializable
    {
        public customHeader()
        {
            Actor = "http://schemas.xmlsoap.org/soap/actor/next";
            MustUnderstand = false;
        }
    
        public System.Xml.Schema.XmlSchema GetSchema()
        {
            return null;
            //throw new NotImplementedException();
        }
    
        public void ReadXml(XmlReader reader)
        {
            //throw new NotImplementedException();
        }
    
        public void WriteXml(XmlWriter writer)
        {
            writer.WriteAttributeString("soap:actor", Actor);
            writer.WriteAttributeString("soap:mustUnderstand", MustUnderstand ? "1" : "0");
            writer.WriteRaw("some encrypted data");
            //get it exactly the way you want it in here without mucking with Xml* property attributes for hours on end
            //writer.WriteElement(...);
        }
    }
    
    0 讨论(0)
  • 2020-12-19 19:47

    I was able to get this done by modifying the auto-generated proxy code manually and simply injecting a class that inherited "SoapHeader" and added the attribute to the method!

    I cannot re-generate or re-fresh the proxy, but it got the job done, and only took 15 minutes.

    0 讨论(0)
  • 2020-12-19 19:54

    Quite an old post but can be usefull for others.

    When integrating the WSDL in Visual Studio, you get a new class deriving from SoapHttpClientProtocol within a new namespace.

    Fortunatelly, this class is partial, this means you can extend it in your code so that the modifications you make are not overwritten when you refresh from the WSDL.

    My WSDL generated class is :

    namespace TheServiceNameSpace {
              public partial class TheClassName : System.Web.Services.Protocols.SoapHttpClientProtocol {
             //Class Code
         }
    }
    

    To add the custom header, I add to my project a new cs file with the following content :

    namespace TheServiceNameSpace 
    {
        public partial class SecurityHeader : SoapHeader
        {
            public String username { get; set; }
            public String password { get; set; }
            public String apikey { get; set; }
        }
    
        public partial class TheClassName
        {
            public SecurityHeader SEC = new SecurityHeader() { username = "xxxx", password = "xxxx", apikey = "xxxx" };
    
            protected override XmlWriter GetWriterForMessage(SoapClientMessage message, int bufferSize)
            {
                message.Headers.Add(SEC);
                return base.GetWriterForMessage(message, bufferSize);
            }
        }
    }
    

    What it does, is :

    • 1 - Create a custom SOAP Header that contains the expected variables
    • 2 - Extend the generated class to add a reference to the new header
    • 3 - Override the GetWriterForMessage method so that I can add my header in the request that will be sent to the service.
    0 讨论(0)
提交回复
热议问题