How to add a custom HTTP header to every WCF call?

后端 未结 13 2311
不知归路
不知归路 2020-11-22 05:33

I have a WCF service that is hosted in a Windows Service. Clients that using this service must pass an identifier every time they\'re calling service methods (because that i

相关标签:
13条回答
  • 2020-11-22 06:08

    The advantage to this is that it is applied to every call.

    Create a class that implements IClientMessageInspector. In the BeforeSendRequest method, add your custom header to the outgoing message. It might look something like this:

    public object BeforeSendRequest(ref System.ServiceModel.Channels.Message request, System.ServiceModel.IClientChannel channel)
    {
        HttpRequestMessageProperty httpRequestMessage;
        object httpRequestMessageObject;
        if (request.Properties.TryGetValue(HttpRequestMessageProperty.Name, out httpRequestMessageObject))
        {
            httpRequestMessage = httpRequestMessageObject as HttpRequestMessageProperty;
            if (string.IsNullOrEmpty(httpRequestMessage.Headers[USER_AGENT_HTTP_HEADER]))
            {
                httpRequestMessage.Headers[USER_AGENT_HTTP_HEADER] = this.m_userAgent;
            }
        }
        else
        {
            httpRequestMessage = new HttpRequestMessageProperty();
            httpRequestMessage.Headers.Add(USER_AGENT_HTTP_HEADER, this.m_userAgent);
            request.Properties.Add(HttpRequestMessageProperty.Name, httpRequestMessage);
        }
        return null;
    }
    

    Then create an endpoint behavior that applies the message inspector to the client runtime. You can apply the behavior via an attribute or via configuration using a behavior extension element.

    Here is a great example of how to add an HTTP user-agent header to all request messages. I am using this in a few of my clients. You can also do the same on the service side by implementing the IDispatchMessageInspector.

    Is this what you had in mind?

    Update: I found this list of WCF features that are supported by the compact framework. I believe message inspectors classified as 'Channel Extensibility' which, according to this post, are supported by the compact framework.

    0 讨论(0)
  • 2020-11-22 06:15

    You can specify custom headers in the MessageContract.

    You can also use < endpoint> headers that are stored in the configuration file and will be copied allong in the header of all the messages sent by the client/service. This is usefull to add some static header easily.

    0 讨论(0)
  • 2020-11-22 06:17

    This is what worked for me, adapted from Adding HTTP Headers to WCF Calls

    // Message inspector used to add the User-Agent HTTP Header to the WCF calls for Server
    public class AddUserAgentClientMessageInspector : IClientMessageInspector
    {
        public object BeforeSendRequest(ref System.ServiceModel.Channels.Message request, IClientChannel channel)
        {
            HttpRequestMessageProperty property = new HttpRequestMessageProperty();
    
            var userAgent = "MyUserAgent/1.0.0.0";
    
            if (request.Properties.Count == 0 || request.Properties[HttpRequestMessageProperty.Name] == null)
            {
                var property = new HttpRequestMessageProperty();
                property.Headers["User-Agent"] = userAgent;
                request.Properties.Add(HttpRequestMessageProperty.Name, property);
            }
            else
            {
                ((HttpRequestMessageProperty)request.Properties[HttpRequestMessageProperty.Name]).Headers["User-Agent"] = userAgent;
            }
            return null;
        }
    
        public void AfterReceiveReply(ref System.ServiceModel.Channels.Message reply, object correlationState)
        {
        }
    }
    
    // Endpoint behavior used to add the User-Agent HTTP Header to WCF calls for Server
    public class AddUserAgentEndpointBehavior : IEndpointBehavior
    {
        public void ApplyClientBehavior(ServiceEndpoint endpoint, ClientRuntime clientRuntime)
        {
            clientRuntime.MessageInspectors.Add(new AddUserAgentClientMessageInspector());
        }
    
        public void AddBindingParameters(ServiceEndpoint endpoint, BindingParameterCollection bindingParameters)
        {
        }
    
        public void ApplyDispatchBehavior(ServiceEndpoint endpoint, EndpointDispatcher endpointDispatcher)
        {
        }
    
        public void Validate(ServiceEndpoint endpoint)
        {
        }
    }
    

    After declaring these classes you can add the new behavior to your WCF client like this:

    client.Endpoint.Behaviors.Add(new AddUserAgentEndpointBehavior());
    
    0 讨论(0)
  • 2020-11-22 06:19

    A bit late to the party but Juval Lowy addresses this exact scenario in his book and the associated ServiceModelEx library.

    Basically he defines ClientBase and ChannelFactory specialisations that allow specifying type-safe header values. I suggesst downloading the source and looking at the HeaderClientBase and HeaderChannelFactory classes.

    John

    0 讨论(0)
  • 2020-11-22 06:20

    If you just want to add the same header to all the requests to the service, you can do it with out any coding!
    Just add the headers node with required headers under the endpoint node in your client config file

    <client>  
      <endpoint address="http://localhost/..." >  
        <headers>  
          <HeaderName>Value</HeaderName>  
        </headers>   
     </endpoint>  
    
    0 讨论(0)
  • 2020-11-22 06:21
    var endpoint = new EndpointAddress(new Uri(RemoteAddress),
                   new[] { AddressHeader.CreateAddressHeader(
                           "APIKey", 
                           "",
                           "bda11d91-7ade-4da1-855d-24adfe39d174") 
                         });
    
    0 讨论(0)
提交回复
热议问题