在现有 WCF SOAP 服务中添加 Http Header 不起作用

Adding Http Header in an existing WCF SOAP Service is not working

我想要一个 HTTP header 到我的 WCF SOAP 服务。我的最终目标是通过此 HTTP header.

发送 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 请求 header 下没有看到 User-Auth header。

我也试过另一种方法

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 header 信息。我正在使用 SOAP UI 发送请求和查看响应。

我该怎么办?我应该更改与 class 相关的服务吗?或者我需要对 web.config 文件进行一些更改?

香皂Header

要添加 SOAP header,请使用以下代码 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 header XML 元素的命名空间 URI。

HTTP Header

添加一个 Http header:

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

并抓住它server-side

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

如果您尝试向客户端请求添加 HTTP 请求 header,您可以按照以下步骤操作。

创建客户端消息检查器。例如:

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 看到请求 header。

client-side 上有比莱昂纳多更好的解决方案。他的解决方案需要手动修改每个请求。 Here 是 ClientMessageInspector 的解决方案,它会自动将 header 添加到每个传出请求。

1: 定义具有覆盖的 MessageInspector: Bellow是唯一一个覆盖方法,其余为空。

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。 Bellow是唯一一个override方法,其余为空

    public class CustomEndpointBehavior : IEndpointBehavior
    {
       public void ApplyClientBehavior(ServiceEndpoint endpoint, ClientRuntime clientRuntime)
       {
          clientRuntime.ClientMessageInspectors.Add(new ClientMessageInspector());
       }
       ...
    }
  1. 最后一步是将新行为添加到 WCF 端点:
Endpoint.EndpointBehaviors.Add(new CustomEndpointBehavior());