C# WCF,从请求中检索信息,找不到时间戳

C# WCF,从请求中检索信息,找不到时间戳,c#,rest,wcf,http,C#,Rest,Wcf,Http,我确实有一个运行完美的WCF restful服务 每当有人向我的服务发送GET或POST请求时,我确实希望检索尽可能多的信息 我使用以下方法检索我的大部分信息: OperationContext context = OperationContext.Current; MessageProperties messageProperties = context.IncomingMessageProperties; RemoteEndpointMessageProperty endpointProp

我确实有一个运行完美的WCF restful服务

每当有人向我的服务发送GET或POST请求时,我确实希望检索尽可能多的信息

我使用以下方法检索我的大部分信息:

OperationContext context = OperationContext.Current;
MessageProperties messageProperties = context.IncomingMessageProperties;

RemoteEndpointMessageProperty endpointProperty =
          messageProperties[RemoteEndpointMessageProperty.Name] as RemoteEndpointMessageProperty;
我确实需要帮助查找请求的时间戳

多谢各位


编辑:对于某些人来说,该问题会提出不相关的问题,因此部分问题被删除。

这取决于您所说的请求时间戳的含义。如果您想知道请求何时离开客户端,那么即使在ASP.NET上,您也没有该信息,而HttpContext.Timestamp属性不可用-服务器只知道何时收到请求

对于WCF本身,没有任何属性可以告诉您何时创建了操作上下文;您可以自己在自定义编码器、自定义消息检查器、自定义协议通道等的WCF堆栈的任何层中,甚至在操作本身中添加这样的属性—对于大多数情况,它们之间的差异是微不足道的

例如,下面的代码显示了在三个位置对请求加时间戳的示例;在我运行的大多数测试中,它们之间的差异最多只有几毫秒

public class StackOverflow_39082986
{
    const string TimestampPropertyName = "MyTimestampProperty";
    class MyTimestampProperty
    {
        public DateTime EncoderTimestamp;
        public DateTime InspectorTimestamp;
    }
    [ServiceContract]
    public interface ITest
    {
        [OperationContract]
        void DoSomething();
    }
    public class Service : ITest
    {
        public void DoSomething()
        {
            var myProp = (MyTimestampProperty)OperationContext.Current.IncomingMessageProperties[TimestampPropertyName];
            var now = DateTime.UtcNow;
            Console.WriteLine("Request timestamps:");
            var timeFormat = "yyyy-MM-dd HH:MM:ss.fffffff";
            Console.WriteLine("  From encoder  : {0}", myProp.EncoderTimestamp.ToString(timeFormat));
            Console.WriteLine("  From inspector: {0}", myProp.InspectorTimestamp.ToString(timeFormat));
            Console.WriteLine("  From operation: {0}", now.ToString(timeFormat));
        }
    }
    class MyInspector : IEndpointBehavior, IDispatchMessageInspector
    {
        public void AddBindingParameters(ServiceEndpoint endpoint, BindingParameterCollection bindingParameters)
        {
        }

        public object AfterReceiveRequest(ref Message request, IClientChannel channel, InstanceContext instanceContext)
        {
            MyTimestampProperty prop;
            if (request.Properties.ContainsKey(TimestampPropertyName))
            {
                prop = (MyTimestampProperty)request.Properties[TimestampPropertyName];
            }
            else
            {
                prop = new MyTimestampProperty();
                request.Properties.Add(TimestampPropertyName, prop);
            }

            prop.InspectorTimestamp = DateTime.UtcNow;
            return null;
        }

        public void ApplyClientBehavior(ServiceEndpoint endpoint, ClientRuntime clientRuntime)
        {
        }

        public void ApplyDispatchBehavior(ServiceEndpoint endpoint, EndpointDispatcher endpointDispatcher)
        {
            endpointDispatcher.DispatchRuntime.MessageInspectors.Add(this);
        }

        public void BeforeSendReply(ref Message reply, object correlationState)
        {
        }

        public void Validate(ServiceEndpoint endpoint)
        {
        }
    }
    public class MyEncoderBindingElement : MessageEncodingBindingElement
    {
        private MessageEncodingBindingElement inner;
        public MyEncoderBindingElement(MessageEncodingBindingElement inner)
        {
            this.inner = inner;
        }
        public override MessageVersion MessageVersion
        {
            get { return this.inner.MessageVersion; }
            set { this.inner.MessageVersion = value; }
        }

        public override BindingElement Clone()
        {
            return new MyEncoderBindingElement((MessageEncodingBindingElement)this.inner.Clone());
        }

        public override MessageEncoderFactory CreateMessageEncoderFactory()
        {
            return new MyEncoderFactory(this.inner.CreateMessageEncoderFactory());
        }

        public override bool CanBuildChannelListener<TChannel>(BindingContext context)
        {
            return context.CanBuildInnerChannelListener<TChannel>();
        }

        public override IChannelListener<TChannel> BuildChannelListener<TChannel>(BindingContext context)
        {
            context.BindingParameters.Add(this);
            return context.BuildInnerChannelListener<TChannel>();
        }

        class MyEncoderFactory : MessageEncoderFactory
        {
            MessageEncoderFactory inner;
            public MyEncoderFactory(MessageEncoderFactory inner)
            {
                this.inner = inner;
            }

            public override MessageEncoder Encoder
            {
                get
                {
                    return new MyEncoder(this.inner.Encoder);
                }
            }

            public override MessageVersion MessageVersion
            {
                get { return this.inner.MessageVersion; }
            }
        }

        class MyEncoder : MessageEncoder
        {
            MessageEncoder inner;
            public MyEncoder(MessageEncoder inner)
            {
                this.inner = inner;
            }

            public override string ContentType
            {
                get { return this.inner.ContentType; }
            }

            public override string MediaType
            {
                get { return this.inner.MediaType; }
            }

            public override MessageVersion MessageVersion
            {
                get { return this.inner.MessageVersion; }
            }

            public override bool IsContentTypeSupported(string contentType)
            {
                return this.inner.IsContentTypeSupported(contentType);
            }

            public override Message ReadMessage(ArraySegment<byte> buffer, BufferManager bufferManager, string contentType)
            {
                var result = this.inner.ReadMessage(buffer, bufferManager, contentType);
                result.Properties.Add(TimestampPropertyName, new MyTimestampProperty { EncoderTimestamp = DateTime.UtcNow });
                return result;
            }

            public override Message ReadMessage(Stream stream, int maxSizeOfHeaders, string contentType)
            {
                var result = this.inner.ReadMessage(stream, maxSizeOfHeaders, contentType);
                result.Properties.Add(TimestampPropertyName, new MyTimestampProperty { EncoderTimestamp = DateTime.UtcNow });
                return result;
            }

            public override void WriteMessage(Message message, Stream stream)
            {
                this.inner.WriteMessage(message, stream);
            }

            public override ArraySegment<byte> WriteMessage(Message message, int maxMessageSize, BufferManager bufferManager, int messageOffset)
            {
                return this.inner.WriteMessage(message, maxMessageSize, bufferManager, messageOffset);
            }
        }
    }
    static Binding GetBinding(bool server)
    {
        var result = new CustomBinding(new BasicHttpBinding());
        if (server)
        {
            for (var i = 0; i < result.Elements.Count; i++)
            {
                var mebe = result.Elements[i] as MessageEncodingBindingElement;
                if (mebe != null)
                {
                    result.Elements[i] = new MyEncoderBindingElement(mebe);
                    break;
                }
            }
        }

        return result;
    }
    public static void Test()
    {
        string baseAddress = "http://" + Environment.MachineName + ":8000/Service";
        ServiceHost host = new ServiceHost(typeof(Service), new Uri(baseAddress));
        ServiceEndpoint endpoint = host.AddServiceEndpoint(typeof(ITest), GetBinding(true), "");
        endpoint.EndpointBehaviors.Add(new MyInspector());
        host.Open();
        Console.WriteLine("Host opened");

        ChannelFactory<ITest> factory = new ChannelFactory<ITest>(GetBinding(false), new EndpointAddress(baseAddress));
        ITest proxy = factory.CreateChannel();
        proxy.DoSomething();

        ((IClientChannel)proxy).Close();
        factory.Close();

        Console.Write("Press ENTER to close the host");
        Console.ReadLine();
        host.Close();
    }
}

这取决于请求的时间戳是什么意思。如果您想知道请求何时离开客户端,那么即使在ASP.NET上,您也没有该信息,而HttpContext.Timestamp属性不可用-服务器只知道何时收到请求

对于WCF本身,没有任何属性可以告诉您何时创建了操作上下文;您可以自己在自定义编码器、自定义消息检查器、自定义协议通道等的WCF堆栈的任何层中,甚至在操作本身中添加这样的属性—对于大多数情况,它们之间的差异是微不足道的

例如,下面的代码显示了在三个位置对请求加时间戳的示例;在我运行的大多数测试中,它们之间的差异最多只有几毫秒

public class StackOverflow_39082986
{
    const string TimestampPropertyName = "MyTimestampProperty";
    class MyTimestampProperty
    {
        public DateTime EncoderTimestamp;
        public DateTime InspectorTimestamp;
    }
    [ServiceContract]
    public interface ITest
    {
        [OperationContract]
        void DoSomething();
    }
    public class Service : ITest
    {
        public void DoSomething()
        {
            var myProp = (MyTimestampProperty)OperationContext.Current.IncomingMessageProperties[TimestampPropertyName];
            var now = DateTime.UtcNow;
            Console.WriteLine("Request timestamps:");
            var timeFormat = "yyyy-MM-dd HH:MM:ss.fffffff";
            Console.WriteLine("  From encoder  : {0}", myProp.EncoderTimestamp.ToString(timeFormat));
            Console.WriteLine("  From inspector: {0}", myProp.InspectorTimestamp.ToString(timeFormat));
            Console.WriteLine("  From operation: {0}", now.ToString(timeFormat));
        }
    }
    class MyInspector : IEndpointBehavior, IDispatchMessageInspector
    {
        public void AddBindingParameters(ServiceEndpoint endpoint, BindingParameterCollection bindingParameters)
        {
        }

        public object AfterReceiveRequest(ref Message request, IClientChannel channel, InstanceContext instanceContext)
        {
            MyTimestampProperty prop;
            if (request.Properties.ContainsKey(TimestampPropertyName))
            {
                prop = (MyTimestampProperty)request.Properties[TimestampPropertyName];
            }
            else
            {
                prop = new MyTimestampProperty();
                request.Properties.Add(TimestampPropertyName, prop);
            }

            prop.InspectorTimestamp = DateTime.UtcNow;
            return null;
        }

        public void ApplyClientBehavior(ServiceEndpoint endpoint, ClientRuntime clientRuntime)
        {
        }

        public void ApplyDispatchBehavior(ServiceEndpoint endpoint, EndpointDispatcher endpointDispatcher)
        {
            endpointDispatcher.DispatchRuntime.MessageInspectors.Add(this);
        }

        public void BeforeSendReply(ref Message reply, object correlationState)
        {
        }

        public void Validate(ServiceEndpoint endpoint)
        {
        }
    }
    public class MyEncoderBindingElement : MessageEncodingBindingElement
    {
        private MessageEncodingBindingElement inner;
        public MyEncoderBindingElement(MessageEncodingBindingElement inner)
        {
            this.inner = inner;
        }
        public override MessageVersion MessageVersion
        {
            get { return this.inner.MessageVersion; }
            set { this.inner.MessageVersion = value; }
        }

        public override BindingElement Clone()
        {
            return new MyEncoderBindingElement((MessageEncodingBindingElement)this.inner.Clone());
        }

        public override MessageEncoderFactory CreateMessageEncoderFactory()
        {
            return new MyEncoderFactory(this.inner.CreateMessageEncoderFactory());
        }

        public override bool CanBuildChannelListener<TChannel>(BindingContext context)
        {
            return context.CanBuildInnerChannelListener<TChannel>();
        }

        public override IChannelListener<TChannel> BuildChannelListener<TChannel>(BindingContext context)
        {
            context.BindingParameters.Add(this);
            return context.BuildInnerChannelListener<TChannel>();
        }

        class MyEncoderFactory : MessageEncoderFactory
        {
            MessageEncoderFactory inner;
            public MyEncoderFactory(MessageEncoderFactory inner)
            {
                this.inner = inner;
            }

            public override MessageEncoder Encoder
            {
                get
                {
                    return new MyEncoder(this.inner.Encoder);
                }
            }

            public override MessageVersion MessageVersion
            {
                get { return this.inner.MessageVersion; }
            }
        }

        class MyEncoder : MessageEncoder
        {
            MessageEncoder inner;
            public MyEncoder(MessageEncoder inner)
            {
                this.inner = inner;
            }

            public override string ContentType
            {
                get { return this.inner.ContentType; }
            }

            public override string MediaType
            {
                get { return this.inner.MediaType; }
            }

            public override MessageVersion MessageVersion
            {
                get { return this.inner.MessageVersion; }
            }

            public override bool IsContentTypeSupported(string contentType)
            {
                return this.inner.IsContentTypeSupported(contentType);
            }

            public override Message ReadMessage(ArraySegment<byte> buffer, BufferManager bufferManager, string contentType)
            {
                var result = this.inner.ReadMessage(buffer, bufferManager, contentType);
                result.Properties.Add(TimestampPropertyName, new MyTimestampProperty { EncoderTimestamp = DateTime.UtcNow });
                return result;
            }

            public override Message ReadMessage(Stream stream, int maxSizeOfHeaders, string contentType)
            {
                var result = this.inner.ReadMessage(stream, maxSizeOfHeaders, contentType);
                result.Properties.Add(TimestampPropertyName, new MyTimestampProperty { EncoderTimestamp = DateTime.UtcNow });
                return result;
            }

            public override void WriteMessage(Message message, Stream stream)
            {
                this.inner.WriteMessage(message, stream);
            }

            public override ArraySegment<byte> WriteMessage(Message message, int maxMessageSize, BufferManager bufferManager, int messageOffset)
            {
                return this.inner.WriteMessage(message, maxMessageSize, bufferManager, messageOffset);
            }
        }
    }
    static Binding GetBinding(bool server)
    {
        var result = new CustomBinding(new BasicHttpBinding());
        if (server)
        {
            for (var i = 0; i < result.Elements.Count; i++)
            {
                var mebe = result.Elements[i] as MessageEncodingBindingElement;
                if (mebe != null)
                {
                    result.Elements[i] = new MyEncoderBindingElement(mebe);
                    break;
                }
            }
        }

        return result;
    }
    public static void Test()
    {
        string baseAddress = "http://" + Environment.MachineName + ":8000/Service";
        ServiceHost host = new ServiceHost(typeof(Service), new Uri(baseAddress));
        ServiceEndpoint endpoint = host.AddServiceEndpoint(typeof(ITest), GetBinding(true), "");
        endpoint.EndpointBehaviors.Add(new MyInspector());
        host.Open();
        Console.WriteLine("Host opened");

        ChannelFactory<ITest> factory = new ChannelFactory<ITest>(GetBinding(false), new EndpointAddress(baseAddress));
        ITest proxy = factory.CreateChannel();
        proxy.DoSomething();

        ((IClientChannel)proxy).Close();
        factory.Close();

        Console.Write("Press ENTER to close the host");
        Console.ReadLine();
        host.Close();
    }
}

最近我发现自己也处于类似的境地,在阅读了来自的精彩答案后,我决定深入挖掘,找出如何从IIS web.config文件中使用他的示例

事实证明,卡洛斯在微软有自己的博客,并且有几篇文章非常详细地介绍了这一主题。顶部的图表非常有用,并且清楚地表明,当服务通过IIS托管时,最接近于直接在线读取客户端消息

这基本上是使用相同的过程完成的,但要在web.config文件中完成,您必须创建一个派生自的类,以便为IIS提供创建BindingElement/Encoder/Factory所需的钩子,如下例所示

我不想重复卡洛斯已经发布的内容,但在解决所有这些问题的过程中,我确实对他的代码做了一些调整。因此,与其偶然发布不适用于他的示例的代码,我将在这里重新发布我的调整

步骤1创建和关联以包装绑定通常使用的原始MessageEncoder,并使包装MessageEncoder将时间戳添加到原始/包装MessageEncoder创建的

注意:这是三个类中的前两个,它们基本上包装对象并通过将调用传递到包装的/内部对象来实现它们的WCF接口,即返回inner.property/method,允许自定义MessageEncoder精确匹配我们基本上要扩展/更改的MessageEncoder的行为。所以,虽然这是一个冗长的答案,但一旦你掌握了所有涉及的部分,它就真的没有那么复杂了。

步骤4更新web.config文件:

添加/更新web.config的部分,以包含对我们刚才在上面的代码中创建的TimestampedTextMsgEncodingExtension的完全限定引用 使用指向bindingConfiguration HttpNoAuthTimestampEncoding的绑定创建/更新端点 添加/更新bindings\customBinding下的bindingConfiguration部分HttpNoAuthTimestampEncoding,以使用我们在bindingElementExtensions部分中为自定义MessageEncoder扩展timestampedTextMsgEncoding分配的名称的元素,以指示通信量应流经该编码器。 元素有一点帮助,但主要是大量的网络搜索和反复试验。特别值得注意的是使用和在HTTP和HTTPS之间切换。相反,basicHttpBinding使用security\@mode=None和security\@mode=Transport


最近,我发现自己也处于类似的境地,在阅读了他的精彩答案后,我决定再深入一点,找出如何让他的例子在f rom一个IIS web.config文件

事实证明,卡洛斯在微软有自己的博客,并且有几篇文章非常详细地介绍了这一主题。顶部的图表非常有用,并且清楚地表明,当服务通过IIS托管时,最接近于直接在线读取客户端消息

这基本上是使用相同的过程完成的,但要在web.config文件中完成,您必须创建一个派生自的类,以便为IIS提供创建BindingElement/Encoder/Factory所需的钩子,如下例所示

我不想重复卡洛斯已经发布的内容,但在解决所有这些问题的过程中,我确实对他的代码做了一些调整。因此,与其偶然发布不适用于他的示例的代码,我将在这里重新发布我的调整

步骤1创建和关联以包装绑定通常使用的原始MessageEncoder,并使包装MessageEncoder将时间戳添加到原始/包装MessageEncoder创建的

注意:这是三个类中的前两个,它们基本上包装对象并通过将调用传递到包装的/内部对象来实现它们的WCF接口,即返回inner.property/method,允许自定义MessageEncoder精确匹配我们基本上要扩展/更改的MessageEncoder的行为。所以,虽然这是一个冗长的答案,但一旦你掌握了所有涉及的部分,它就真的没有那么复杂了。

步骤4更新web.config文件:

添加/更新web.config的部分,以包含对我们刚才在上面的代码中创建的TimestampedTextMsgEncodingExtension的完全限定引用 使用指向bindingConfiguration HttpNoAuthTimestampEncoding的绑定创建/更新端点 添加/更新bindings\customBinding下的bindingConfiguration部分HttpNoAuthTimestampEncoding,以使用我们在bindingElementExtensions部分中为自定义MessageEncoder扩展timestampedTextMsgEncoding分配的名称的元素,以指示通信量应流经该编码器。 元素有一点帮助,但主要是大量的网络搜索和反复试验。特别值得注意的是使用和在HTTP和HTTPS之间切换。相反,basicHttpBinding使用security\@mode=None和security\@mode=Transport


但我不能让代码正常工作意味着什么?到底发生了什么?请阅读。谢谢你的链接。我的意思是,我不确定如何在我的项目中实现和调用HttpRequest。cheersAgain,当你编译并运行它时会发生什么?它说,对象不包含请求的定义,那么你从哪里得到这些代码,为什么它应该应用于WCF?如果以兼容模式在IIS中运行,则可以使用System.Web.HttpContext.Current.Request。但我无法使该代码正常工作意味着什么?到底发生了什么?请阅读。谢谢你的链接。我的意思是,我不确定如何在我的项目中实现和调用HttpRequest。cheersAgain,当你编译并运行它时会发生什么?它说,对象不包含请求的定义,那么你从哪里得到这些代码,为什么它应该应用于WCF?如果以兼容模式在IIS中运行,则可以使用System.Web.HttpContext.Current.Request。
using System.ServiceModel.Channels;
using System.ServiceModel.Description;
using System.ServiceModel.Configuration;
using System.Configuration;

namespace WCF.Sample
{
    public class TimestampedTextMsgEncodingBindingElement : MessageEncodingBindingElement, IWsdlExportExtension, IPolicyExportExtension
    {
        private readonly TextMessageEncodingBindingElement inner;

        public TimestampedTextMsgEncodingBindingElement(TextMessageEncodingBindingElement inner)
        {
            this.inner = inner;
        }

        public TimestampedTextMsgEncodingBindingElement()
        {
            inner = new TextMessageEncodingBindingElement();
        }

        public TimestampedTextMsgEncodingBindingElement(MessageVersion messageVersion, Encoding writeEnconding)
        {
            inner = new TextMessageEncodingBindingElement(messageVersion, writeEnconding);
        }

        public override MessageEncoderFactory CreateMessageEncoderFactory()
        {
            return new TimestampedMsgEncoderFactory(inner.CreateMessageEncoderFactory());
        }

        #region Pass-through MessageEncoderBindingElement implementations

        public override BindingElement Clone()
        {
            return new TimestampedTextMsgEncodingBindingElement((TextMessageEncodingBindingElement)inner.Clone());
        }

        public override MessageVersion MessageVersion { get { return inner.MessageVersion; } set { inner.MessageVersion = value; } }
        public Encoding WriteEncoding { get { return inner.WriteEncoding; } set { inner.WriteEncoding = value; } }
        public Int32 MaxReadPoolSize { get { return inner.MaxReadPoolSize; } set { inner.MaxReadPoolSize = value; } }
        public Int32 MaxWritePoolSize { get { return inner.MaxWritePoolSize; } set { inner.MaxWritePoolSize = value; } }
        public XmlDictionaryReaderQuotas ReaderQuotas { get { return inner.ReaderQuotas; } set { inner.ReaderQuotas = value; } }

        public override Boolean CanBuildChannelListener<TChannel>(BindingContext context)
        {
            return context.CanBuildInnerChannelListener<TChannel>();
            //return inner.CanBuildChannelFactory<TChannel>(context);
        }

        public override IChannelListener<TChannel> BuildChannelListener<TChannel>(BindingContext context)
        {
            context.BindingParameters.Add(this);
            return context.BuildInnerChannelListener<TChannel>();
            //return inner.BuildChannelListener<TChannel>(context);         
        }

        public void ExportContract(WsdlExporter exporter, WsdlContractConversionContext context)
        {
            ((IWsdlExportExtension)inner).ExportContract(exporter, context);
        }

        public void ExportEndpoint(WsdlExporter exporter, WsdlEndpointConversionContext context)
        {
            ((IWsdlExportExtension)inner).ExportEndpoint(exporter, context);
        }

        public void ExportPolicy(MetadataExporter exporter, PolicyConversionContext context)
        {
            ((IPolicyExportExtension)inner).ExportPolicy(exporter, context);
        }

        #endregion Pass-through MessageEncoderBindingElement implementations
    }
}
using System;
using System.Xml;
using System.Text;
using System.ServiceModel.Channels;
using System.ServiceModel.Description;
using System.ServiceModel.Configuration;
using System.Configuration;

namespace WCF.Sample
{
    public class TimestampedTextMsgEncodingExtension : BindingElementExtensionElement
    {
        private MessageVersion _MessageVersion = MessageVersion.Soap11;
        private Encoding _Encoding = Encoding.UTF8;
        private Int32 _MaxReadPoolSize = -1;
        private Int32 _MaxWritePoolSize = -1;
        private XmlDictionaryReaderQuotas _ReaderQuotas = null;

        public override Type BindingElementType { get { return typeof(TimestampedTextMsgEncodingBindingElement); } }

        protected override BindingElement CreateBindingElement()
        {
            TimestampedTextMsgEncodingBindingElement eb = new TimestampedTextMsgEncodingBindingElement(_MessageVersion, _Encoding);
            if (_MaxReadPoolSize > -1) eb.MaxReadPoolSize = _MaxReadPoolSize;
            if (_MaxWritePoolSize > -1) eb.MaxWritePoolSize = MaxWritePoolSize;
            if (_ReaderQuotas != null) eb.ReaderQuotas = _ReaderQuotas;

            return eb;
        }

        [ConfigurationProperty("messageVersion", DefaultValue = "Soap11", IsRequired = false)]
        public String messageVersion
        {
            set
            {
                switch (value)
                {
                    case "Soap11":
                        _MessageVersion = MessageVersion.Soap11;
                        break;

                    case "Soap12":
                        _MessageVersion = MessageVersion.Soap12;
                        break;

                    case "Soap11WSAddressing10":
                        _MessageVersion = MessageVersion.Soap11WSAddressing10;
                        break;

                    case "Soap12WSAddressing10":
                        _MessageVersion = MessageVersion.Soap12WSAddressing10;
                        break;

                    case "Soap11WSAddressingAugust2004":
                        _MessageVersion = MessageVersion.Soap11WSAddressingAugust2004;
                        break;

                    case "Soap12WSAddressingAugust2004":
                        _MessageVersion = MessageVersion.Soap12WSAddressingAugust2004;
                        break;

                    default:
                        throw new NotSupportedException("\"" + value + "\" is not a supported message version.");
                }
            }
        }

        [ConfigurationProperty("writeEncoding", DefaultValue = "Utf8TextEncoding", IsRequired = false)]
        public String writeEncoding
        {
            set
            {
                switch (value)
                {
                    case "Utf8TextEncoding":
                        _Encoding = Encoding.UTF8;
                        break;

                    case "Utf16TextEncoding":
                        _Encoding = Encoding.Unicode;
                        break;

                    case "UnicodeFffeTextEncoding":
                        _Encoding = Encoding.BigEndianUnicode;
                        break;

                    default:
                        _Encoding = Encoding.GetEncoding(value);
                        break;
                }
            }
        }

        [ConfigurationProperty("maxReadPoolSize", IsRequired = false)]
        public Int32 MaxReadPoolSize { get { return _MaxReadPoolSize; } set { _MaxReadPoolSize = value; } }

        [ConfigurationProperty("maxWritePoolSize", IsRequired = false)]
        public Int32 MaxWritePoolSize { get { return _MaxWritePoolSize; } set { _MaxWritePoolSize = value; } }

        [ConfigurationProperty("readerQuotas", IsRequired = false)]
        public XmlDictionaryReaderQuotas ReaderQuotas { get { return _ReaderQuotas; } set { _ReaderQuotas = value; } }
    }
}
DateTime SOAPMsgReceived = (DateTime)System.ServiceModel.OperationContext.Current.IncomingMessageProperties[TimestampedMsgEncoder.TimestampProp];