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.
Keith Elder nicely compares ASMX to WCF here. Check it out.
Another comparison of ASMX and WCF can be found here - I don't 100% agree with all the points there, but it might give you an idea.
WCF is basically "ASMX on stereoids" - it can be all that ASMX could - plus a lot more!.
ASMX is:
- easy and simple to write and configure
- only available in IIS
- only callable from HTTP
WCF can be:
- hosted in IIS, a Windows Service, a Winforms application, a console app - you have total freedom
- used with HTTP (REST and SOAP), TCP/IP, MSMQ and many more protocols
In short: WCF is here to replace ASMX fully.
Check out the WCF Developer Center on MSDN.
Update: link seems to be dead - try this: What Is Windows Communication Foundation?
Best Answer
One word: DON'T !
Services should be stateless whenever possible - it makes life just that much easier.
If you need to keep state between calls, put it in a persistance container, e.g. a database, and report back the ID under which it can be found for the next call.
Marc
If you really must keep session (really?? Think about it twice - better yet: three times) - then WCF offers per-session calls on certain bindings (protocols).
The
basicHttpBinding
which is closest to ASMX webservices for one does not support sessions. You'll need to usewsHttpBinding
for internet-facing apps, ornetTcpBinding
for internal intranet-oriented services.Check out the MSDN docs on using sessions with WCF.