3

もう少し深く掘り下げて、新しい詳細を発見しました。

一般に「UriTemplate」が「AfterReceiveRequest」の 2 回目の呼び出しを引き起こすのではなく、内部のオプションのパラメーターが原因です。

メソッドを呼び出すと

http:///myserver/result/val1

AfterReceiveRequest は 2 回呼び出されます。

次のようなすべての可能なパラメータを渡すと

http:///myserver/result/val1/val2/val3

無駄な呼び出しはありません。その動作は意図したとおりですか?

UriTemplate = "result/{para1=null}/{para2=null}/{para3=null}"

--- 最初の投稿に続き、参考までに ---

WCF REST サービス システムを実装しているときに、http ヘッダーの問題に行き詰まりました。

私の中には、属性で定義されServiceContractたメソッドがあるので、経由で呼び出すことができますUriTemplateWebGet

http://server/resource/val1/val2 ...

それ以外の

http://server/resource?para1=val1&para2=val2 ...

(互換性の理由からこれが必要です。)

また、http-headersコレクションには重要な値があり、それを読む必要があります。IDispatchMessageInspectorしたがって、このインスペクターを実装してEndpointDispatchers MessageInspectorsコレクションに追加します。これにより、AfterReceiveRequestWCF によって呼び出され、アクセスWebOperationContext.Current.IncomingRequest.Headersして目的の値を読み取ることができます。

問題:

WCFUriTemplateは、宛先メソッドへの 2 番目の要求を生成することによって -mapping を解決しますが、元の呼び出しから生成された 2 番目の呼び出しにヘッダー エントリを渡しません。そのためAfterReceiveRequest(そしてもちろんBeforeSendReplyも) は 2 回呼び出されますが、実際のクライアント呼び出しからのヘッダー値は最初の呼び出しにのみ含まれます。

AfterReceiveRequestまた、最初の呼び出しから 2 番目の呼び出しにヘッダー値を渡すための「特別な方法」を実装するために、最初の呼び出しと2 番目の呼び出しを関連付ける方法が見つかりませんでした。

UriTemplate-redirected 2 番目の呼び出しにヘッダーをルーティングするように WCF に指示する方法はありますか?

明確にするために、いくつかのコードフラグメントを次に示します。

[ServiceContract]
public interface IMyService
{
    [WebGet(UriTemplate = "result/{para1=null}/{para2=null}/{para3=null}")]
    bool MyMethod(string para1, string para2, string para3);
}

[ServiceBehavior(InstanceContextMode = InstanceContextMode.Single)]
[MyServiceInspectorBeavior]
public class MyService : IMyService
{
    public bool MyMethod(string para1, string para2, string para3)
    {
        return DoTheWork();
    }
    //...
}

public class MyServiceInspectorBeavior : Attribute, IServiceBehavior
{

    public void ApplyDispatchBehavior(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase)
    {
        foreach (EndpointDispatcher epDispatcher in serviceHostBase.ChannelDispatchers.OfType<ChannelDispatcher>().SelectMany(cDispatcher => cDispatcher.Endpoints))
        {
            epDispatcher.DispatchRuntime.MessageInspectors.Add(new MyInspector());
        }
    }

    //...
}

public class MyInspector : IDispatchMessageInspector
{
    //this is invoked twice for each client request, 
    //but only at the first call the header is present...
    public object AfterReceiveRequest(ref Message request, IClientChannel channel, InstanceContext instanceContext)
    {
        WebHeaderCollection webOpContext = 
                      WebOperationContext.Current.IncomingRequest.Headers;
        string xForwardedIp = webOpContext["X-FORWARDED-IP"];
        WriteLog(xForwardedIp);

        return OperationContext.Current.IncomingMessageProperties["ActivityId"];
    }
    //...
}
4

0 に答える 0