Reputation: 63126
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 problem I have is that they need a SoapHeader with some specific information in it, but I don't have any way of doing it. The only real things I have for the service is a proxy method that was created (MyMethod) that I can pass my message to. How can I set/send a soap header with it as well?
All of the services I've had, I have been able to use the automatically bound items from Visual Studio.
Upvotes: 3
Views: 11337
Reputation: 1062492
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...).
Upvotes: 1
Reputation: 31
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 :
Upvotes: 2
Reputation: 15227
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(...);
}
}
Upvotes: 0
Reputation: 63126
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.
Upvotes: 2