significado example ejemplos componentes wcf

example - ¿Cómo agregar un encabezado HTTP personalizado a cada llamada WCF?



wcf vs web api (12)

Tengo un servicio WCF alojado en un servicio de Windows. Los clientes que usan este servicio deben pasar un identificador cada vez que llaman a métodos de servicio (porque ese identificador es importante para lo que debería hacer el método llamado). Pensé que era una buena idea poner de alguna manera este identificador en la información del encabezado WCF.

Si es una buena idea, ¿cómo puedo agregar el identificador automáticamente a la información del encabezado? En otras palabras, siempre que el usuario llame al método WCF, el identificador debe agregarse automáticamente al encabezado.

ACTUALIZACIÓN: los clientes que utilizan el servicio WCF son aplicaciones de Windows y Windows Mobile (usando Compact Framework).


Aquí hay otra solución útil para agregar manualmente encabezados HTTP personalizados a su solicitud WCF de cliente utilizando ChannelFactory como proxy. Esto tendría que hacerse para cada solicitud, pero es suficiente como una demostración simple si solo necesita probar su proxy por separado para preparar plataformas que no sean .NET.

// create channel factory / proxy ... using (OperationContextScope scope = new OperationContextScope(proxy)) { OperationContext.Current.OutgoingMessageProperties[HttpRequestMessageProperty.Name] = new HttpRequestMessageProperty() { Headers = { { "MyCustomHeader", Environment.UserName }, { HttpRequestHeader.UserAgent, "My Custom Agent"} } }; // perform proxy operations... }


Esto es lo que funcionó para mí, adaptado de Agregar encabezados HTTP a las llamadas WCF

// 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) { } }

Después de declarar estas clases, puede agregar el nuevo comportamiento a su cliente WCF de la siguiente manera:

client.Endpoint.Behaviors.Add(new AddUserAgentEndpointBehavior());


Esto es similar a la respuesta de NimsDotNet, pero muestra cómo hacerlo mediante programación.

Simplemente agregue el encabezado a la encuadernación

var cl = new MyServiceClient(); var eab = new EndpointAddressBuilder(cl.Endpoint.Address); eab.Headers.Add( AddressHeader.CreateAddressHeader("ClientIdentification", // Header Name string.Empty, // Namespace "JabberwockyClient")); // Header Value cl.Endpoint.Address = eab.ToEndpointAddress();


Esto funciona para mí

TestService.ReconstitutionClient _serv = new TestService.TestClient ();

using (OperationContextScope contextScope = new OperationContextScope(_serv.InnerChannel)) { HttpRequestMessageProperty requestMessage = new HttpRequestMessageProperty(); requestMessage.Headers["apiKey"] = ConfigurationManager.AppSettings["apikey"]; OperationContext.Current.OutgoingMessageProperties[HttpRequestMessageProperty.Name] = requestMessage; _serv.Method(Testarg); }


Lo agregas a la llamada usando:

using (OperationContextScope scope = new OperationContextScope((IContextChannel)channel)) { MessageHeader<string> header = new MessageHeader<string>("secret message"); var untyped = header.GetUntypedHeader("Identity", "http://www.my-website.com"); OperationContext.Current.OutgoingMessageHeaders.Add(untyped); // now make the WCF call within this using block }

Y luego, en el lado del servidor, lo agarras usando:

MessageHeaders headers = OperationContext.Current.IncomingMessageHeaders; string identity = headers.GetHeader<string>("Identity", "http://www.my-website.com");


Los bindings contexto en .NET 3.5 pueden ser justo lo que estás buscando. Hay tres fuera de la caja: BasicHttpContextBinding, NetTcpContextBinding y WSHttpContextBinding. El protocolo de contexto pasa básicamente los pares clave-valor en el encabezado del mensaje. Consulte el artículo Administrar el estado con servicios duraderos en la revista MSDN.


Puede especificar encabezados personalizados en MessageContract .

También puede usar los encabezados <endpoint> que están almacenados en el archivo de configuración y se copiarán en el encabezado de todos los mensajes enviados por el cliente / servicio. Esto es útil para agregar un encabezado estático fácilmente.


Si entiendo tu requerimiento correctamente, la respuesta simple es: no puedes.

Esto se debe a que el cliente del servicio WCF puede ser generado por cualquier tercero que use su servicio.

SI tiene el control de los clientes de su servicio, puede crear una clase de cliente base que agregue el encabezado deseado y herede el comportamiento en las clases de trabajadores.


Si solo desea agregar el mismo encabezado a todas las solicitudes al servicio, ¡puede hacerlo sin ningún tipo de codificación!
Simplemente agregue el nodo de encabezados con los encabezados necesarios debajo del nodo del punto final en su archivo de configuración del cliente

<client> <endpoint address="http://localhost/..." > <headers> <HeaderName>Value</HeaderName> </headers> </endpoint>


Un poco tarde para la fiesta, pero Juval Lowy aborda este escenario exacto en su book y la biblioteca ServiceModelEx asociada.

Básicamente define las especializaciones de ClientBase y ChannelFactory que permiten especificar valores de cabecera de tipo seguro. Sugiero descargar la fuente y mirar las clases HeaderClientBase y HeaderChannelFactory.

John


La ventaja de esto es que se aplica a todas las llamadas.

Cree una clase que implemente IClientMessageInspector . En el método BeforeSendRequest, agregue su encabezado personalizado al mensaje saliente. Puede parecerse a esto:

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; }

A continuación, cree un comportamiento de punto final que aplique el inspector de mensajes al tiempo de ejecución del cliente. Puede aplicar el comportamiento a través de un atributo o a través de la configuración utilizando un elemento de extensión de comportamiento.

Aquí hay un gran example de cómo agregar un encabezado de agente de usuario HTTP a todos los mensajes de solicitud. Estoy usando esto en algunos de mis clientes. También puede hacer lo mismo en el lado del servicio implementando IDispatchMessageInspector .

¿Es esto lo que tienes en mente?

Actualización: Encontré esta list de características de WCF que son compatibles con el marco compacto. Creo que los inspectores de mensajes se clasificaron como "Extensibilidad de canal" que, de acuerdo con esta publicación, son compatibles con el marco compacto.


var endpoint = new EndpointAddress(new Uri(RemoteAddress), new[] { AddressHeader.CreateAddressHeader("APIKey", "", "bda11d91-7ade-4da1-855d-24adfe39d174") });