Welcome to Windows Communication Foundation (WCF)
Top Tasks :

WCF Team Bloggers

Browse by Tags

All Tags » Service Model » Indigo » Samples   (RSS)

  • AutoHeader Extension

    I frequently get asked how to add a header to every outgoing request so I wrote up a quick reusable approach. This adds some extension methods to the IContextChannel class for working with auto-added headers. The headers are stored between calls in an IExtension. public static class AutoHeaderExtension { class AutoHeaderContextExtension : Dictionary<XName, MessageHeader>, IExtension<IContextChannel> { public void Attach(IContextChannel owner) { } public void Detach(IContextChannel owner) { } } public static void AddAutoHeader( this IContextChannel proxy, string name, string ns, object value ) { AutoHeaderContextExtension extension = proxy.Extensions.Find<AutoHeaderContextExtension>(); if (extension == null ) { extension = new AutoHeaderContextExtension(); proxy.Extensions.Add(extension); } extension[XName.Get(name, ns)] = MessageHeader.CreateHeader(name, ns, value ); } public static IEnumerable<MessageHeader> GetAutoHeaders( this IContextChannel proxy) { AutoHeaderContextExtension extension = proxy.Extensions.Find<AutoHeaderContextExtension>(); if (extension == null ) { return Enumerable.Empty<MessageHeader>(); } return extension.Values; } public static void RemoveAutoHeader( this IContextChannel proxy, string name, string ns) { AutoHeaderContextExtension extension = proxy.Extensions.Find<AutoHeaderContextExtension>(); if (extension != null ) { extension.Remove(XName.Get(name, ns)); } } } If you combine that with a message inspector that adds the headers on to each message, then you get a collection of headers that are added to every outgoing request. public class AutoHeaderMessageInspectorBehavior : IEndpointBehavior { class AutoHeaderMessageInspector : IClientMessageInspector { public void AfterReceiveReply( ref Message reply, object correlationState) { } public object BeforeSendRequest( ref Message request, IClientChannel channel) { foreach (MessageHeader header in channel.GetAutoHeaders()) { request.Headers.Add(header); } return null ; } } public void AddBindingParameters(ServiceEndpoint endpoint, BindingParameterCollection bindingParameters) { } public void ApplyClientBehavior(ServiceEndpoint endpoint, ClientRuntime clientRuntime) { clientRuntime.MessageInspectors.Add( new AutoHeaderMessageInspector()); } public void ApplyDispatchBehavior(ServiceEndpoint endpoint, EndpointDispatcher endpointDispatcher) { } public void Validate(ServiceEndpoint endpoint) { } } Here's an example using this extension. [ServiceContract] Read More...
  • Using Call Context Initializers for Culture

    Let's build on a few earlier samples to actually demonstrate a working call context initializer. I'll start with yesterday's skeleton for a call context initializer and behavior . To that skeleton I'll add implementations of BeforeInvoke and AfterInvoke that initialize the operation thread with custom culture information and then clean the thread up once the operation return. class CultureInitializer : ICallContextInitializer { CultureInfo newInfo; public CultureInitializer(CultureInfo newInfo) { this .newInfo = newInfo; } public void AfterInvoke( object correlationState) { Thread.CurrentThread.CurrentCulture = correlationState as CultureInfo; } public object BeforeInvoke(InstanceContext instanceContext, IClientChannel channel, Message message) { CultureInfo oldInfo = Thread.CurrentThread.CurrentCulture; Thread.CurrentThread.CurrentCulture = newInfo; return oldInfo; } } Then, I'll fill out ApplyDispatchBehavior to apply my call context initializer to every operation on the given endpoint. class CultureInitializerBehavior : IEndpointBehavior { CultureInfo newInfo; public CultureInitializerBehavior(CultureInfo newInfo) { this .newInfo = newInfo; } public void AddBindingParameters(ServiceEndpoint endpoint, BindingParameterCollection bindingParameters) { } public void ApplyClientBehavior(ServiceEndpoint endpoint, ClientRuntime clientRuntime) { } public void ApplyDispatchBehavior(ServiceEndpoint endpoint, EndpointDispatcher endpointDispatcher) { foreach (DispatchOperation operation in endpointDispatcher.DispatchRuntime.Operations) { operation.CallContextInitializers.Add( new CultureInitializer(newInfo)); } } public void Validate(ServiceEndpoint endpoint) { } } Finally, I'll take last week's custom fault encoding sample and install my behavior. Notice that the only change at the service level is to add the behavior to the endpoint behavior collection. If I had written the code to apply the behavior in an attribute or configuration file, either of those approaches would have worked as well. [ServiceContract] public interface IMyService { [OperationContract] Message Fail(); } public class MyService : IMyService { public Message Fail() { XmlDocument document = new XmlDocument(); document.LoadXml( "<tag attributeName=\"value\"><moretags>blah</moretags></tag>" ); throw new FaultException<XmlElement>(document.FirstChild as XmlElement); } } public class Program { static void Main( string [] args) { string address = "http://localhost:8000/" Read More...

Copyright © 2006 Microsoft Corporation. All Rights Reserved. | Terms of Use | Privacy Statement | Contact Us