Reputation: 306
I'm trying to consume a SOAP webservices provided by a third party. I don't have any control of that webservice. I'm consuming the webservice using a Low Code platform called OutSystems. OutSystems unfortunately doesn't recognize a SOAP header that has to be send with the request so I'll have to add it myself by extending the platform functionality with some custom c# code.
The SOAP Extensibility API gives me access to the WCF ClientCredentials, ServiceEndpoint, IClientChannel and CommunicationState objects. It also provides a method to register an endpoint behavior, using a IEndpointBehavior object.
Using svcutil I've been able to generate proxy classes for the data of the message, including the SOAP header that I should add.
Ideally I'm looking for a way to instantiate an object of the proxy of the header and then somehow pass that to the service. But here is where i'm stuck. I/m not able to find a way to use that object as a SOAP header.
The documentation of OutSytems also provides an example about adding a soap header using .net code. They use MessageHeader.CreateHeader to create a new element with a given element name, namespace and value. So this is also a place where i'm stuck. It would be great if I could use the proxy class here, but this will only allow me to set it as the value. This way I end up with a duplicate 'root' element.
Using the code below:
class AddSoapHeaderMessageInspector : IClientMessageInspector {
object IClientMessageInspector.BeforeSendRequest(ref Message request, IClientChannel channel) {
// before sending a request, add a new SOAP header, specifying its name, namespace and value
request.Headers.Add(MessageHeader.CreateHeader("MySoapHeader", "http://my-namespace.com", mySOAPHeader));
return request;
}
void IClientMessageInspector.AfterReceiveReply(ref Message reply, object correlationState) {
// here you would handle the web service response
}
}
Would result in XML like
<MySoapHeader><MySoapHeader><element1><element2></MySoapHeader></MySoapHeader>
While it should look like
<MySoapHeader><element1><element2></MySoapHeader>
The solution we have now is one where we've implemented a class that extends MessageHeader. In the OnWriteHeaderContents of that class we manually write the content of the header in code. Unfortunately this is cause some namespace issues at the server side.
I'm posting this on stackoverflow instead of the OutSystems forum because I consider this more of a WCF/C# question than an OutSystems question.
Upvotes: 1
Views: 1638
Reputation: 3964
You can add soap header in the implementation class by implementing IClientMessageInspector interface.
public class ClientMessageLogger : IClientMessageInspector
{
public void AfterReceiveReply(ref Message reply, object correlationState)
{
}
public object BeforeSendRequest(ref Message request, IClientChannel channel)
{
MessageHeader header = MessageHeader.CreateHeader("MySoapHeader", "http://my-namespace.com", "asdas");
request.Headers.Add(header);
return null;
}
}
Add clientmessagelogger to clientruntime:
[AttributeUsage(AttributeTargets.Interface | AttributeTargets.Class, AllowMultiple = false)]
public class CustContractBehaviorAttribute : Attribute, IContractBehavior, IContractBehaviorAttribute
{
public Type TargetContract => throw new NotImplementedException();
public void AddBindingParameters(ContractDescription contractDescription, ServiceEndpoint endpoint, BindingParameterCollection bindingParameters)
{
return;
}
public void ApplyClientBehavior(ContractDescription contractDescription, ServiceEndpoint endpoint, ClientRuntime clientRuntime)
{
clientRuntime.ClientMessageInspectors.Add(new ClientMessageLogger());
}
public void ApplyDispatchBehavior(ContractDescription contractDescription, ServiceEndpoint endpoint, DispatchRuntime dispatchRuntime)
{
}
public void Validate(ContractDescription contractDescription, ServiceEndpoint endpoint)
{
return;
}
}
Add Attribute to Interface of proxy class:
[CustContractBehavior]
public interface IService {
}
This is the soap message received by the server:
To learn more about IClientMessageInspector, please refer to the following link:
Upvotes: 0