WCF:通过装饰为操作注入自定义标头

时间:2013-09-26 11:30:56

标签: wcf wcf-extensions

嗨,如果操作是装饰的,我需要在消息中注入一个自定义标题。

到目前为止我做了什么? 1)通过继承Attribute和IOperationBehavior创建一个Attribute 2)使用操作

附加自定义OperationInvoker

属性:

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

接口:

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

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

现在的问题是,我不知道在哪里修改消息头,我可以通过operationDiscription.Messages []访问消息,但是文档说任何修改都会产生意想不到的结果。

谢谢, 阿维纳什

1 个答案:

答案 0 :(得分:1)

没关系:)这很简单:) ..你可以访问IOperationInvoker中的OperationContext

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; 
        }
    }
}