Tengo un servicio WCF que está 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 debe hacer el método llamado). Pensé que es una buena idea poner este identificador de alguna manera 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, cada vez que el usuario llama al método WCF, el identificador debe agregarse automáticamente al encabezado.
ACTUALIZACIÓN: Los clientes que usan el servicio WCF son aplicaciones de Windows y aplicaciones de Windows Mobile (usando Compact Framework).
Respuestas:
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. Podría verse más o menos así:
Luego, cree un comportamiento de punto final que aplique el inspector de mensajes al tiempo de ejecución del cliente. Puede aplicar el comportamiento mediante un atributo o mediante la configuración utilizando un elemento de extensión de comportamiento.
Aquí hay un gran ejemplo 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 tenías en mente?
Actualización: encontré esta lista de características de WCF que son compatibles con el marco compacto. Creo que los inspectores de mensajes clasificados como 'Extensibilidad de canal' que, según esta publicación, son compatibles con el marco compacto.
fuente
OutgoingMessageProperties
es lo que necesita para acceder a los encabezados HTTP, no losOutgoingMessageHeaders
encabezados SOAP.Lo agrega a la llamada usando:
Y luego, del lado del servidor, lo agarras usando:
fuente
OperationContextScope
(yOperationContext
) sonThreadStatic
: la respuesta de Mark Good funcionará sin depender deThreadStatic
elementos.Si solo desea agregar el mismo encabezado a todas las solicitudes al servicio, ¡puede hacerlo sin ninguna codificación!
Simplemente agregue el nodo de encabezados con los encabezados requeridos debajo del nodo de punto final en el archivo de configuración de su cliente
fuente
MessageHeader
), no encabezados HTTP.Aquí hay otra solución útil para agregar manualmente encabezados HTTP personalizados a la solicitud WCF de su 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 unitariamente su proxy en preparación para plataformas que no sean .NET.fuente
Esto es similar a la respuesta de NimsDotNet, pero muestra cómo hacerlo mediante programación.
Simplemente agregue el encabezado al enlace
fuente
fuente
Esto es lo que funcionó para mí, adaptado de Agregar encabezados HTTP a llamadas WCF
Después de declarar estas clases, puede agregar el nuevo comportamiento a su cliente WCF de esta manera:
fuente
Esto funciona para mi
fuente
Los enlaces de contexto en .NET 3.5 pueden ser justo lo que está buscando. Hay tres listos para usar: BasicHttpContextBinding, NetTcpContextBinding y WSHttpContextBinding. El protocolo de contexto básicamente pasa pares clave-valor en el encabezado del mensaje. Consulte el artículo Gestión del estado con servicios duraderos en la revista MSDN.
fuente
Si entiendo su requisito correctamente, la respuesta simple es: no puede.
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 trabajo.
fuente
Puede especificar encabezados personalizados en MessageContract .
También puede usar encabezados <endpoint> que se almacenan 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.
fuente
MessageHeader
), no encabezados HTTP.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:Al igual que en la respuesta de Mark Good y Paulwhit, necesitamos subclase
IEndpointBehavior
para inyectar nuestroHttpHeaderMessageInspector
en nuestro cliente WCF.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:
EndpointConfiguration
se generó una enumeración para pasar al constructor; tal vez su implementación no tendrá esto)AddHttpHeaderMessageEndpointBehavior
a losEndpoint
comportamientos del cliente.¡Finalmente, usa tu cliente!
La solicitud HTTP resultante debe contener sus encabezados HTTP y tener un aspecto similar a este:
fuente
Un poco tarde para la fiesta, pero Juval Lowy aborda este escenario exacto en su libro y la biblioteca ServiceModelEx asociada .
Básicamente, define las especializaciones de ClientBase y ChannelFactory que permiten especificar valores de encabezado de tipo seguro. Sugiero descargar la fuente y mirar las clases HeaderClientBase y HeaderChannelFactory.
Juan
fuente