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



我想向我的WCF SOAP Service提供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

SOAP 标头

若要添加 SOAP 标头,请在客户端使用以下代码:

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
}

然后,在服务器端,使用以下方法获取它:

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

铌。 ns标头 XML 元素的命名空间 URI。

HTTP 标头

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

如果您尝试将 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 的请求标头。

客户端有比莱昂纳多更好的解决方案。他的解决方案需要手动修改每个请求。以下是 ClientMessageInspector 的解决方案,它会自动将标头添加到每个传出请求。

1:使用覆盖定义消息检查器:波纹管是唯一一种覆盖方法,其余为空。

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());

最新更新