By defining an attribute that implements IContactBehavior and IWsdlExportExtension and set that attribute on your service contract, you can easily add Soap Headers to your wsdl (see http://wcfextras.codeplex.com/ for more information)
But now I need to set a Soap Header contract in the wsdl on all Operationcontracts and this time I cannot set an attribute.
Following code (called from IWsdlExportExtension.ExportEndPoint) doesn't work, but does work when called from the SoapHeaderAttributes (that executes an IWsdlExportExtension.ExportContract)
foreach (OperationDescription operationDescription in context.ContractConversionContext.Contract.Operations)
{
AddSoapHeader(operationDescription, "SomeHeaderObject", typeof(SomeHeaderObject), SoapHeaderDirection.InOut);
}
internal static void AddSoapHeader(OperationDescription operationDescription, string name, Type type, SoapHeaderDirection direction)
{
MessageHeaderDescription header = GetMessageHeader(name, type);
bool input = ((direction & SoapHeaderDirection.In) == SoapHeaderDirection.In);
bool output = ((direction & SoapHeaderDirection.Out) == SoapHeaderDirection.Out);
foreach (MessageDescription msgDescription in operationDescription.Messages)
{
if ((msgDescription.Direction == MessageDirection.Input && input) ||
(msgDescription.Direction == MessageDirection.Output && output))
msgDescription.Headers.Add(header);
}
}
internal static MessageHeaderDescription GetMessageHeader(string name, Type type)
{
string headerNamespace = SoapHeaderHelper.GetNamespace(type);
MessageHeaderDescription messageHeaderDescription = new MessageHeaderDescription(name, headerNamespace);
messageHeaderDescription.Type = type;
return messageHeaderDescription;
}
Anyone has an idea how to apply this code on all operations (without using attributes) and by doing this, adding the contract of the header to the wsdl ?
The IEndpointBehavior has the following interface:
ApplyDispatchBehavior(ServiceEndpoint endPoint, EndPointDispatcher endpointDispatcher);
You can add Soap Headers to the wsdl for operations by iterating over the endpoint.Contract.Operations in the ApplyDispatchBehavior.
Here you have the complete solution that worked for me:
void IEndpointBehavior.ApplyDispatchBehavior(ServiceEndpoint endpoint, EndpointDispatcher endpointDispatcher)
{
foreach (OperationDescription operationDescription in endpoint.Contract.Operations)
{
foreach (MessageDescription msgDescription in operationDescription.Messages)
{
AddSoapHeader(operationDescription, "SomeHeaderObject", typeof(SomeHeaderObject), SoapHeaderDirection.InOut);
}
}
}
internal static void AddSoapHeader(OperationDescription operationDescription, string name, Type type, SoapHeaderDirection direction)
{
MessageHeaderDescription header = GetMessageHeader(name, type);
bool input = ((direction & SoapHeaderDirection.In) == SoapHeaderDirection.In);
bool output = ((direction & SoapHeaderDirection.Out) == SoapHeaderDirection.Out);
foreach (MessageDescription msgDescription in operationDescription.Messages)
{
if ((msgDescription.Direction == MessageDirection.Input && input) ||
(msgDescription.Direction == MessageDirection.Output && output))
msgDescription.Headers.Add(header);
}
}
internal static MessageHeaderDescription GetMessageHeader(string name, Type type)
{
string headerNamespace = SoapHeaderHelper.GetNamespace(type);
MessageHeaderDescription messageHeaderDescription = new MessageHeaderDescription(name, headerNamespace);
messageHeaderDescription.Type = type;
return messageHeaderDescription;
}
The SoapHeaderHelper can be found in the WcfExtras.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With