Si vous souhaitez ajouter des en-têtes HTTP personnalisés à chaque appel WCF d'une manière orientée objet, ne cherchez pas plus loin.
Tout comme dans la réponse de Mark Good et paulwhit, nous devons créer une sous-classe IClientMessageInspector
pour injecter les en-têtes HTTP personnalisés dans la requête WCF. Cependant, rendons l'inspecteur plus générique en acceptant un dictionnaire contenant les en-têtes que nous voulons ajouter:
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 ...
}
Tout comme dans la réponse de Mark Good et paulwhit, nous devons créer une sous-classe IEndpointBehavior
pour l'injecter HttpHeaderMessageInspector
dans notre 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 ...
}
La dernière partie nécessaire pour terminer notre approche orientée objet consiste à créer une sous-classe de notre client généré automatiquement WCF (j'ai utilisé le guide de référence du service Web WCF de Microsoft pour générer un client WCF).
Dans mon cas, je dois attacher une clé API à l'en- x-api-key
tête HTML.
La sous-classe effectue les opérations suivantes:
- appelle le constructeur de la classe de base avec les paramètres requis (dans mon cas un
EndpointConfiguration
énumération a été générée pour passer au constructeur - peut-être que votre implémentation ne l'aura pas)
- Définit les en-têtes qui doivent être attachés à chaque demande
- S'attache
AddHttpHeaderMessageEndpointBehavior
aux Endpoint
comportements du client
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);
}
}
Enfin, utilisez votre client!
var apiKey = 'XXXXXXXXXXXXXXXXXXXXXXXXX';
var client = new Client (apiKey);
var result = client.SomeRequest()
La requête HTTP résultante doit contenir vos en-têtes HTTP et ressembler à ceci:
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>