wcfwcf-extensions

WCF: Injecting custom headers for an operation through decoration


Hi I need to inject a custom header in the message if the operation is decorated.

What have I done so far? 1) Created an Attribute by inheriting Attribute and IOperationBehavior 2) Attached a custom OperationInvoker with the operation

Attribute:

public class RankAttribute : Attribute, IOperationBehavior
{ 
     public void ApplyDispatchBehavior(OperationDescription operationDescription, DispatchOperation dispatchOperation)
    {
        dispatchOperation.Invoker = new PublishMessageInvoker(dispatchOperation.Invoker);
    }
    //rest of the methods
}

Interface:

public interface INullableService
{
    [OperationContract]
    [FaultContract(typeof(BusinessServiceException))]
    [Rank]
    NullableResponse NullChecking(NullableRequest request);

    [OperationContract]
    [FaultContract(typeof(BusinessServiceException))]
    NullableResponse NullChecking2(NullableRequest request);
}

Now the problem is, I dont know where to modify the message header, I get access to the Message via operationDiscription.Messages[] but the documentation says that any modification will yield unexpected results.

Thanks, Avinash


Solution

  • never mind :) it was trivial :) .. you get access to OperationContext in IOperationInvoker

    public class PublishMessageInvoker : IOperationInvoker
    {
        private IOperationInvoker invoker;
    
    
        public PublishMessageInvoker(IOperationInvoker invoker)
        {
            logger.Info("PublishMessageInvoker");
            this.invoker = invoker;
    
        }
    
        public object[] AllocateInputs()
        {
    
            if (invoker == null)
                return null;
            return this.invoker.AllocateInputs();
        }
    
        public object Invoke(object instance, object[] inputs, out object[] outputs)
        {
           OperationContext.Current.OutgoingMessageHeaders.Add(
                MessageHeader.CreateHeader(
                    "customheader",
                    "asnjnjdhbhb.com",
                    "MyAction")
                    );
            return this.invoker.Invoke(instance, inputs, out outputs);
        }
    
        public IAsyncResult InvokeBegin(object instance, object[] inputs, AsyncCallback callback, object state)
        {
    
            if (invoker == null)
                return null;
            return this.invoker.InvokeBegin(instance, inputs, callback, state);
        }
    
        public object InvokeEnd(object instance, out object[] outputs, IAsyncResult result)
        {
    
            if (invoker == null)
            {
                outputs = null;
                return null;
            }
            return this.invoker.InvokeEnd(instance, out outputs, result);
        }
    
        public bool IsSynchronous
        {
            get {
    
                if (invoker == null) return true;
                return this.invoker.IsSynchronous; 
            }
        }
    }