Si desea agregar encabezados HTTP personalizados a cada llamada WCF de una manera orientada a objetos, no busque más.
Al igual que en la respuesta de Mark Good y paulwhit, necesitamos una subclase IClientMessageInspector
para inyectar los encabezados HTTP personalizados en la solicitud WCF. Sin embargo, hagamos que el inspector sea más genérico al aceptar un diccionario que contiene los encabezados que queremos agregar:
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 ...
}
Al igual que en la respuesta de Mark Good y Paulwhit, necesitamos subclase IEndpointBehavior
para inyectar nuestro HttpHeaderMessageInspector
en nuestro cliente 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 última parte necesaria para finalizar nuestro enfoque orientado a objetos es crear una subclase de nuestro cliente generado automáticamente por WCF (utilicé la Guía de referencia del servicio web WCF de Microsoft para generar un cliente WCF).
En mi caso, necesito adjuntar una clave API al x-api-key
encabezado HTML.
La subclase hace lo siguiente:
- llama al constructor de la clase base con los parámetros requeridos (en mi caso,
EndpointConfiguration
se generó una enumeración para pasar al constructor; tal vez su implementación no tendrá esto)
- Define los encabezados que se deben adjuntar a cada solicitud
- Se adhiere
AddHttpHeaderMessageEndpointBehavior
a los Endpoint
comportamientos 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);
}
}
¡Finalmente, usa tu cliente!
var apiKey = 'XXXXXXXXXXXXXXXXXXXXXXXXX';
var client = new Client (apiKey);
var result = client.SomeRequest()
La solicitud HTTP resultante debe contener sus encabezados HTTP y tener un aspecto similar a este:
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>