configurar wcf encoding binary net-tcp

configurar - ¿Cómo se modifica programáticamente la codificación del mensaje WCF para NetTcp?



configurar web.config wcf (2)

¿Has intentado crear un CustomBinding en lugar de la configuración de NetTcpBinding que tienes? Algo como esto:

NetTcpBinding binding = new NetTcpBinding(); // get binding from somewhere var elements = binding.CreateBindingElements(); BindingElementCollection newElements = new BindingElementCollection(); foreach ( var e in elements ) { if ( e is MessageEncodingBindingElement ) { newElements.Add(new MyMessageEncodingBindingElement()); } else { newElements.Add(e); } } CustomBinding cb = new CustomBinding(newElements);

Tengo una aplicación de intranet personalizada que no tiene requisitos de interoperabilidad. Construimos programáticamente un canal NetTcp en modo dúplex para pasar mensajes. Queríamos cambiar la codificación del mensaje, pero no hemos podido averiguar cómo hacerlo.

El enfoque que hemos tomado (sin éxito) ha sido extender el NetTcpBinding en una nueva clase llamada LeanTcpBinding de la siguiente manera:

internal class LeanTcpBinding : NetTcpBinding { private static readonly ILog _log = LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType); public override BindingElementCollection CreateBindingElements() { BindingElementCollection bindingElementCollection = base.CreateBindingElements(); BindingElement encodingElement = bindingElementCollection.FirstOrDefault( bindingElement => bindingElement is BinaryMessageEncodingBindingElement); if (encodingElement != null) { int index = bindingElementCollection.IndexOf(encodingElement); bindingElementCollection.RemoveAt(index); bindingElementCollection.Insert(index, new LeanBinaryMessageEncodingBindingElement()); } else { _log.Warn("Encoding not found"); } return bindingElementCollection; } }

Obviamente, estamos tratando de reemplazar el BinaryMessageEncodingBindingElement predeterminado por el nuestro. Para comenzar, el LeanBinaryMessageEncodingBindingElement es una extensión de BinaryMessageEncodingBindingElement de la siguiente manera:

internal class LeanBinaryMessageEncodingBindingElement : MessageEncodingBindingElement { private readonly BinaryMessageEncodingBindingElement _bindingElement; /// /// Initializes a new instance of the class. /// public LeanBinaryMessageEncodingBindingElement() { _bindingElement = new BinaryMessageEncodingBindingElement(); } /// /// Initializes a new instance of the class. /// /// The binding element. public LeanBinaryMessageEncodingBindingElement(BinaryMessageEncodingBindingElement bindingElement) { _bindingElement = bindingElement; } /// /// Initializes a new instance of the class. /// /// The element to be cloned. /// The binding element. public LeanBinaryMessageEncodingBindingElement(MessageEncodingBindingElement elementToBeCloned, BinaryMessageEncodingBindingElement bindingElement) : base(elementToBeCloned) { _bindingElement = bindingElement; } /// /// When overridden in a derived class, returns a copy of the binding element object. /// /// /// A object that is a deep clone of the original. /// public override BindingElement Clone() { return new LeanBinaryMessageEncodingBindingElement( (BinaryMessageEncodingBindingElement)_bindingElement.Clone()); } /// /// When overridden in a derived class, creates a factory for producing message encoders. /// /// /// The used to produce message encoders. /// public override MessageEncoderFactory CreateMessageEncoderFactory() { return new LeanBinaryMessageEncoderFactory(_bindingElement.CreateMessageEncoderFactory()); } /// /// When overridden in a derived class, gets or sets the message version that can be handled by the message encoders produced by the message encoder factory. /// /// /// The used by the encoders produced by the message encoder factory. /// public override MessageVersion MessageVersion { get { return _bindingElement.MessageVersion; } set { _bindingElement.MessageVersion = value; } } }

Cuando trato de usar el enlace, hago exactamente lo que creo que debería hacer ... reemplaza el BinaryMessageEncodingBindingElement. Sin embargo, nunca recibo llamadas a LeanBinaryMessageEncodingBindingElement.CreateMessageEncoderFactory (), aunque se están intercambiando mensajes en el canal.

Alguien tiene alguna sugerencia sobre cómo hacer esto correctamente?


Kenny Wolf aclaró lo que faltaba y está documentado en la entrada del blog a continuación.

http://kennyw.com/?p=170

Para los impacientes, el problema es que, por defecto, MessageEncoderBindingElement no se agrega a los parámetros de enlace del contexto. Como resultado, cuando el transporte va más tarde a encontrar MessageEncoderBindingElement, no puede encontrar el que yo (o usted) ha creado y tiene la falla silenciosa que anoté en mi publicación original.

Lamentablemente, deberá sobrescribir todos los métodos CanBuildXXX y BuildXXX de la siguiente manera para asegurarse de que está agregando el elemento de enlace a los parámetros de enlace del contexto.

public override bool CanBuildChannelFactory(BindingContext context) { if (context == null) { throw new ArgumentNullException("context"); } context.BindingParameters.Add(this); return context.CanBuildInnerChannelFactory(); } public override bool CanBuildChannelListener(BindingContext context) { if (context == null) { throw new ArgumentNullException("context"); } context.BindingParameters.Add(this); return context.CanBuildInnerChannelListener(); } public override IChannelFactory BuildChannelFactory(BindingContext context) { if (context == null) { throw new ArgumentNullException("context"); } context.BindingParameters.Add(this); return context.BuildInnerChannelFactory(); } public override IChannelListener BuildChannelListener(BindingContext context) { if (context == null) { throw new ArgumentNullException("context"); } context.BindingParameters.Add(this); return context.BuildInnerChannelListener(); }