web-dev-qa-db-ja.com

既存のWCFにHttpヘッダーを追加するSOAPサービスが機能していません

WCF SOAPサービスへのHTTPヘッダーを作成したいと思います。私の最終目標は、このHTTPヘッダーを介してAPIキーを送信することです。

以下は私のコードです:

[ServiceBehavior(Namespace = "http://****.com/**/1.1")]
public class MyWcfSvc : IMyVerify
{
    const int MaxResponseSize = 0xffff; // 64K max size - Normally it will be MUCH smaller than this

    private static readonly NLogLogger Logger;

    static MyWcfSvc()
    {
        Logger = new NLogLogger();
        // Add an HTTP Header to an outgoing request 
        HttpRequestMessageProperty requestMessage = new HttpRequestMessageProperty();
        requestMessage.Headers["User-Auth"] = "MyHttpHeaderValue";
        OperationContext.Current.OutgoingMessageProperties[HttpRequestMessageProperty.Name] = requestMessage;
    }
}

HTTPリクエストヘッダーの下にUser-Authヘッダーが表示されません。

私も別の方法で試しました。

public AnalyzeResponse Analyze(AnalyzeRequest analyzeRequest)
    {
        HttpRequestMessageProperty requestMessage = new HttpRequestMessageProperty();
        requestMessage.Headers["User-Auth"] = "MyHttpHeaderValue";
        OperationContext.Current.OutgoingMessageProperties[HttpRequestMessageProperty.Name] = requestMessage;
.
.
. Rest of the service implementation
.
.
.
}

しかし、それでも、リクエストメッセージにHTTPヘッダー情報が表示されません。 SOAP UIを使用して、リクエストを送信し、レスポンスを表示しています。

どうすればいいですか?クラスに関連するサービスに変更を加えることを想定していますか?または、web.configファイルに変更を加える必要がありますか?

9
Sameer

SOAPヘッダーを追加するには、次のコードを使用しますclient-side

using (OperationContextScope scope = new OperationContextScope((IContextChannel)channel))
{
    MessageHeader<string> header = new MessageHeader<string>("MyHttpHeaderValue");
    var untyped = header.GetUntypedHeader("User-Auth", ns);
    OperationContext.Current.OutgoingMessageHeaders.Add(untyped);

    // now make the WCF call within this using block
}

そして、server-side、以下を使用して取得します。

MessageHeaders headers = OperationContext.Current.IncomingMessageHeaders;
string identity = headers.GetHeader<string>("User-Auth", ns);

注意。 ns isヘッダーXML要素の名前空間URI。

Httpヘッダーを追加するには:

// Add a HTTP Header to an outgoing request 
HttpRequestMessageProperty requestMessage = new HttpRequestMessageProperty();
requestMessage.Headers["MyHttpHeader"] = "MyHttpHeaderValue";
OperationContext.Current.OutgoingMessageProperties[HttpRequestMessageProperty.Name] = requestMessage;

そしてそれをつかむためにサーバー側

IncomingWebRequestContext request = WebOperationContext.Current.IncomingRequest; 
WebHeaderCollection headers = request.Headers; 
Console.WriteLine(request.Method + " " + request.UriTemplateMatch.RequestUri.AbsolutePath); 

foreach (string headerName in headers.AllKeys)
{ 
    Console.WriteLine(headerName + ": " + headers[headerName]); 
}
6
Leonardo Seccia

HTTPリクエストヘッダーをクライアントリクエストに追加しようとしている場合は、以下の手順に従うことができます。

クライアントメッセージインスペクターを作成します。例えば:

public class CustomInspector : IClientMessageInspector
{
    public void AfterReceiveReply(ref Message reply, object correlationState)
    {
    }

    public object BeforeSendRequest(ref Message request, IClientChannel channel)
    {
        HttpRequestMessageProperty reqProps = request.Properties[HttpRequestMessageProperty.Name] as HttpRequestMessageProperty;
        if(reqProps == null)
        {
            reqProps = new HttpRequestMessageProperty();
        }

        reqProps.Headers.Add("Custom-Header", "abcd");
        request.Properties[HttpRequestMessageProperty.Name] = reqProps;

        return null;
    }
}

このインスペクターをロードするエンドポイント動作を作成します。

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

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

    public void ApplyDispatchBehavior(ServiceEndpoint endpoint, EndpointDispatcher endpointDispatcher)
    {
    }

    public void Validate(ServiceEndpoint endpoint)
    {
    }
}

最後に、この動作をエンドポイントに追加します。

class Program
{
    static void Main(string[] args)
    {
        ChannelFactory<ICalculator> factory = new ChannelFactory<ICalculator>("BasicHttpsBinding_ICalculator");
        factory.Endpoint.EndpointBehaviors.Add(new CustomBehavior());
        var client = factory.CreateChannel();

        var number = client.Add(1, 2);

        Console.WriteLine(number.ToString());
    }
}

上記の例は私の側で機能します。 Fiddlerでリクエストヘッダーを見ることができました。

1
Chun Liu

クライアント側には、レオナルドよりも優れたソリューションがあります。彼のソリューションでは、各リクエストを手動で変更する必要があります。 Here は、各送信リクエストにヘッダーを自動的に追加するClientMessageInspectorを使用したソリューションです。

1:オーバーライドを使用してMessageInspectorを定義する:以下は唯一のオーバーライドメソッドであり、残りは空です。

public class ClientMessageInspector : IClientMessageInspector
{
    public object BeforeSendRequest(ref Message request, IClientChannel channel)
    {
        HttpRequestMessageProperty property = new HttpRequestMessageProperty();
        property.Headers["User-Agent"] = "value";
        request.Properties.Add(HttpRequestMessageProperty.Name, property);
        return null;
    }
...
}
  1. このメッセージインスペクターをEndPointBehaviorにバインドします。ベローは唯一のオーバーライドメソッドであり、残りは空です。

    public class CustomEndpointBehavior : IEndpointBehavior
    {
       public void ApplyClientBehavior(ServiceEndpoint endpoint, ClientRuntime clientRuntime)
       {
          clientRuntime.ClientMessageInspectors.Add(new ClientMessageInspector());
       }
       ...
    }
  1. 最後のステップは、新しい動作をWCFエンドポイントに追加することです。
Endpoint.EndpointBehaviors.Add(new CustomEndpointBehavior());
0
Karel Kral