3

複数の操作を持つ WCF サービスを使用しています。このサービスでは、その操作のいずれかを呼び出すたびに、送信メッセージ プロパティを追加する必要があります。

現時点では、コード内でサービスを呼び出すたびにプロパティを追加しています。

これを行うための私のコードは次のとおりです。

using (new OperationContextScope(client.InnerChannel))
{
      OperationContext.Current.OutgoingMessageProperties.Add("P1", "Test User");
      OperationContext.Current.OutgoingMessageProperties.Add("P2", "Test Type");
      response = client.process(request);
}

これらのメッセージ プロパティを動的に追加する WCF 拡張機能を作成するにはどうすればよいですか?

拡張機能についての知識はほとんどありませんが、これらのヘッダーを傍受して追加するのに十分ではありません。

4

3 に答える 3

4

メッセージにヘッダーを自動的に追加するには、IClientMessageInspectorを実装する必要があります。送信メッセージのすべてを変更できます。

編集2:

public class ClientMessageInspector : IClientMessageInspector
{
    public object BeforeSendRequest(ref Message request, IClientChannel channel)
    {
        //following example is for adding http header.   
        //If you have another protocol you can add any other message  
        //manipulation code instead.

        //HttpResponseMessageProperty.Name returns "httpResponse".

        HttpResponseMessageProperty httpProp = null;
        if (request.Properties.ContainsKey(HttpResponseMessageProperty.Name))
        {
            httpProp = (HttpResponseMessageProperty)request.Properties[HttpResponseMessageProperty.Name];
        }
        else
        {
            httpProp = new HttpResponseMessageProperty();
            request.Properties.Add(HttpResponseMessageProperty.Name, httpProp);
        }

        httpProp.Headers.Add("YouHeader", "YourValue");

        //as I mentioned you can change a message in a way you need
        request.Properties.Add("P1", "Test User");
        request.Headers.Add(MessageHeader.CreateHeader("P1", "htt p://site.com/", "Test User"));

        return null;
    }

    public void AfterReceiveReply(ref Message reply, object correlationState) { }
}

public class ClientMessageInspectorBehavior : IEndpointBehavior
{
    public void AddBindingParameters(ServiceEndpoint endpoint, BindingParameterCollection bindingParameters)
    {
    }

    public void ApplyClientBehavior(ServiceEndpoint endpoint, ClientRuntime clientRuntime)
    {
        clientRuntime.MessageInspectors.Add(new ClientMessageInspector());
    }

    public void ApplyDispatchBehavior(ServiceEndpoint endpoint, EndpointDispatcher endpointDispatcher)
    {

    }

    public void Validate(ServiceEndpoint endpoint)
    {
    }
}

public class ClientMessageInspectorExtensionElement : BehaviorExtensionElement
{
    protected override object CreateBehavior()
    {
        return new ClientMessageInspectorBehavior();
    }

    public override Type BehaviorType
    {
        get
        {
            return typeof(ClientMessageInspectorBehavior);
        }
    }
}

設定ファイルは次のようになります。

<?xml version="1.0" encoding="utf-8" ?>
<configuration>

  <system.serviceModel>
    <client>
          <endpoint 
            address="http://localhost:8000/CoolerService" 
            behaviorConfiguration="coolerBehaviour" 
            binding="webHttpBinding"
            contract="CoolerService.ICoolerService"
            name="coolerEndpoint">
          </endpoint>
    </client>

    <extensions>
      <behaviorExtensions>
        <add name="customHeaderAdder" type="Extensions.ClientMessageInspectorExtensionElement, Extensions" />
      </behaviorExtensions>
    </extensions>

    <behaviors>
      <endpointBehaviors>
        <behavior name="coolerBehaviour">
          <customHeaderAdder />
        </behavior>
      </endpointBehaviors>
    </behaviors>

  </system.serviceModel>

</configuration>
于 2014-05-04T21:09:58.030 に答える
1

私の意見では、次のようなものOperationContext.Currentを作成せずに簡単に設定できます。OperationScope

OperationContext.Current = new OperationContext(client.InnerChannel);
OperationContext.Current.OutgoingMessageProperties.Add("P1", "Test User");

これは最初は悪い習慣のように見えるかもしれませんが、ドキュメントOperationContext.Currentを見ると、プロパティが実際には現在のスレッドにスコープされている ( ThreadStatic属性を使用) ため、スレッド セーフであることがわかります。

はクライアント チャネルにバインドされているため、同じスレッド内のの他のインスタンスはclientメッセージ プロパティを追加しないことに注意してください。OperationContext

于 2017-03-09T14:50:24.170 に答える
0

前の回答が言ったように IClientMessageInspector を実装しますが、HTTP ヘッダーを追加する場合は、BeforeSendRequest 内で使用したものと同様のコード ブロックを使用します。

using (new OperationContextScope((IContextChannel)channel))
{
      OperationContext.Current.OutgoingMessageProperties.Add("P1", "Test User");
      OperationContext.Current.OutgoingMessageProperties.Add("P2", "Test Type");
      response = client.process(request);
}
于 2015-01-08T21:01:18.557 に答える