Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to add custom soap headers in wcf?

Tags:

wcf

wcf-client

Can I add Custom SOAP header in WCF incoming/outgoing messages in basicHttpBinding, like we can add custom authentication header in ASMX web services? Those custom SOAP header should be accessible using .net 2.0/1.1 web service clients (accessible by WSDL.EXE tool) .

like image 968
nRk Avatar asked Dec 29 '09 18:12

nRk


People also ask

How do I add a SOAP header in WCF?

To publish metadata for WCF services using custom SOAP headers, you should manually create a Web Services Description Language (WSDL) file. You can use the externalMetadataLocation attribute of the <serviceMetadata> element in the Web. config file that the wizard generates to specify the location of the WSDL file.

How do I add a custom HTTP header to every WCF call?

You can apply the behavior via an attribute or via configuration using a behavior extension element. Here is a great example of how to add an HTTP user-agent header to all request messages. I am using this in a few of my clients.


2 Answers

Check out the WCF Extras on Codeplex - it's an easy extension library for WCF which offers - among other things - custom SOAP headers.

Another option is to use WCF message contracts in your WCF service - this also easily allows you to define and set WCF SOAP headers.

[MessageContract]
public class BankingTransaction
{
  [MessageHeader]
  public Operation operation;
  [MessageHeader] 
  public DateTime transactionDate;

  [MessageBodyMember] 
  private Account sourceAccount;
  [MessageBodyMember] 
  private Account targetAccount;
  [MessageBodyMember] 
  public int amount;
}

Here, the "operation" and the "transactionDate" are defined as SOAP headers.

If none of those methods help, then you should check out the concept of WCF Message Inspectors which you can write as extensions. They allow you to e.g. inject certain headers into the message on every outgoing call on the client, and retrieving those from the message on the server for your use.

See this blog post Handling custom SOAP headers via WCF Behaviors for a starting point on how to write a message inspector, and how to include it in your project setup.

The client side IClientMessageInspector defines two methods BeforeSendRequest and AfterReceiveReply while the server side IDispatchMessageInspector has the opposite methods, i.e. AfterReceiveRequest and BeforeSendReply.

With this, you could add headers to every message going across the wire (or selectively only to a few).

Here's a snippet from a IClientMessageInspector implementor we use to automagically transmit the locale information (language and culture info) across from the clients to the server - should give you an idea how to get started:

public object BeforeSendRequest(ref Message request, IClientChannel channel)
{
    International intlHeader = new International();
    intlHeader.Locale = CultureInfo.CurrentUICulture.TwoLetterISOLanguageName;

    MessageHeader header = MessageHeader.CreateHeader(WSI18N.ElementNames.International, WSI18N.NamespaceURI, intlHeader);
    request.Headers.Add(header);

    return null;
}

On the server side, you'd then check for the presence of those headers, and if present, extract them from the SOAP envelope and use them.

UPDATE: okay, you're clients are on .NET 2.0 and not using WCF - good news is, this should still work just fine - see this blog post Custom SOAP Headers: WCF and ASMX for details. You could still use the message inspector on the server side to sniff and extract the custom headers being sent by your .NET 2.0 clients.

like image 91
marc_s Avatar answered Oct 18 '22 03:10

marc_s


This solution was simpler for me:

            var client = "Your Service Client"; 
            using (var scope = new OperationContextScope(client.InnerChannel))
            {
                System.Xml.XmlDocument document = new XmlDocument();
                XmlElement element = document.CreateElement("wsse", "UsernameToken", "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd");

                XmlElement newChild = null;
                newChild = document.CreateElement("wsse", "Username", "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd");
                newChild.InnerText = "finance";
                element.AppendChild(newChild);

                newChild = document.CreateElement("wsse", "CorporationCode", "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd");
                newChild.InnerText = "387";
                element.AppendChild(newChild);

                MessageHeader messageHeader = MessageHeader.CreateHeader("UsernameToken", "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd", element, false);

                OperationContext.Current.OutgoingMessageHeaders.Add(messageHeader);

                var result = client.GetCorporations(new CorporationType { pageNo = 1 });
            }
like image 21
B.Tekkan Avatar answered Oct 18 '22 02:10

B.Tekkan