如何以编程方式更改NetTcp的WCF消息编码?

Aja*_*axx 8 binary wcf encoding net-tcp

我有一个没有互操作性要求的自定义Intranet应用程序.我们以双工模式编程构造NetTcp通道以传递消息.我们想要更改消息编码,但无法弄清楚如何实现这一点.

我们采取的方法(失败)是将NetTcpBinding扩展为一个名为LeanTcpBinding的新类,如下所示:


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;
    }
}
Run Code Online (Sandbox Code Playgroud)

显然,我们正在尝试用我们自己的替换默认的BinaryMessageEncodingBindingElement.只是为了开始使用,LeanBinaryMessageEncodingBindingElement是BinaryMessageEncodingBindingElement的扩展,如下所示:


 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; }
        }
 }
Run Code Online (Sandbox Code Playgroud)

当我尝试使用绑定时,它完全按照我认为它应该做的...它取代了BinaryMessageEncodingBindingElement.但是,即使通过通道交换消息,我也永远不会调用LeanBinaryMessageEncodingBindingElement.CreateMessageEncoderFactory().

任何人对如何正确地做这个有任何建议?

Aja*_*axx 7

Kenny Wolf澄清了遗漏的内容,并在下面的博客文章中记录了这些内容.

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

对于不耐烦的问题是,默认情况下,MessageEncoderBindingElement不会将自身添加到上下文的绑定参数中.因此,当稍后传输找到MessageEncoderBindingElement时,它找不到我(或您)创建的那个并且具有我在原始帖子中记录的静默失败.

不幸的是,您必须按如下方式覆盖所有CanBuildXXX和BuildXXX方法,以确保将绑定元素添加到上下文的绑定参数中.


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