Se si desidera aggiungere intestazioni HTTP personalizzate a ogni chiamata WCF in modo orientato agli oggetti, non cercare oltre.
Proprio come nella risposta di Mark Good e Paul, dobbiamo sottoclassare IClientMessageInspector
per iniettare le intestazioni HTTP personalizzate nella richiesta WCF. Tuttavia, rendiamo l'ispettore più generico accettando un dizionario contenente le intestazioni che vogliamo aggiungere:
public class HttpHeaderMessageInspector : IClientMessageInspector
{
private Dictionary<string, string> Headers;
public HttpHeaderMessageInspector(Dictionary<string, string> headers)
{
Headers = headers;
}
public object BeforeSendRequest(ref Message request, IClientChannel channel)
{
// ensure the request header collection exists
if (request.Properties.Count == 0 || request.Properties[HttpRequestMessageProperty.Name] == null)
{
request.Properties.Add(HttpRequestMessageProperty.Name, new HttpRequestMessageProperty());
}
// get the request header collection from the request
var HeadersCollection = ((HttpRequestMessageProperty)request.Properties[HttpRequestMessageProperty.Name]).Headers;
// add our headers
foreach (var header in Headers) HeadersCollection[header.Key] = header.Value;
return null;
}
// ... other unused interface methods removed for brevity ...
}
Proprio come nella risposta di Mark Good e Paul, dobbiamo sottoclassare IEndpointBehavior
per iniettarci HttpHeaderMessageInspector
nel nostro client WCF.
public class AddHttpHeaderMessageEndpointBehavior : IEndpointBehavior
{
private IClientMessageInspector HttpHeaderMessageInspector;
public AddHttpHeaderMessageEndpointBehavior(Dictionary<string, string> headers)
{
HttpHeaderMessageInspector = new HttpHeaderMessageInspector(headers);
}
public void ApplyClientBehavior(ServiceEndpoint endpoint, ClientRuntime clientRuntime)
{
clientRuntime.ClientMessageInspectors.Add(HttpHeaderMessageInspector);
}
// ... other unused interface methods removed for brevity ...
}
L'ultima parte necessaria per completare il nostro approccio orientato agli oggetti, è creare una sottoclasse del nostro client generato automaticamente WCF (ho usato la Guida di riferimento al servizio Web WCF di Microsoft per generare un client WCF).
Nel mio caso, devo collegare una chiave API a x-api-key
HTML.
La sottoclasse procede come segue:
- chiama il costruttore della classe base con i parametri richiesti (nel mio caso a
EndpointConfiguration
stato generato enum per passare al costruttore - forse la tua implementazione non avrà questo)
- Definisce le intestazioni che devono essere associate a ogni richiesta
- Si attacca
AddHttpHeaderMessageEndpointBehavior
ai Endpoint
comportamenti del cliente
public class Client : MySoapClient
{
public Client(string apiKey) : base(EndpointConfiguration.SomeConfiguration)
{
var headers = new Dictionary<string, string>
{
["x-api-key"] = apiKey
};
var behaviour = new AddHttpHeaderMessageEndpointBehavior(headers);
Endpoint.EndpointBehaviors.Add(behaviour);
}
}
Infine, usa il tuo client!
var apiKey = 'XXXXXXXXXXXXXXXXXXXXXXXXX';
var client = new Client (apiKey);
var result = client.SomeRequest()
La richiesta HTTP risultante dovrebbe contenere le intestazioni HTTP e avere un aspetto simile al seguente:
POST http://localhost:8888/api/soap HTTP/1.1
Cache-Control: no-cache, max-age=0
Connection: Keep-Alive
Content-Type: text/xml; charset=utf-8
Accept-Encoding: gzip, deflate
x-api-key: XXXXXXXXXXXXXXXXXXXXXXXXX
SOAPAction: "http://localhost:8888/api/ISoapService/SomeRequest"
Content-Length: 144
Host: localhost:8888
<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
<s:Body>
<SomeRequestxmlns="http://localhost:8888/api/"/>
</s:Body>
</s:Envelope>