WebMessageEncoderFactory.cs source code in C# .NET

Source code for the .NET framework in C#

                        

Code:

/ 4.0 / 4.0 / untmp / DEVDIV_TFS / Dev10 / Releases / RTMRel / ndp / cdf / src / NetFx35 / System.ServiceModel.Web / System / ServiceModel / Channels / WebMessageEncoderFactory.cs / 1305376 / WebMessageEncoderFactory.cs

                            //---------------------------------------------------------------- 
// Copyright (c) Microsoft Corporation.  All rights reserved.
//---------------------------------------------------------------

namespace System.ServiceModel.Channels 
{
    using System; 
    using System.Globalization; 
    using System.IO;
    using System.Runtime; 
    using System.ServiceModel.Diagnostics;
    using System.Text;
    using System.Xml;
    using System.Diagnostics; 

    class WebMessageEncoderFactory : MessageEncoderFactory 
    { 
        WebMessageEncoder messageEncoder;
 
        public WebMessageEncoderFactory(Encoding writeEncoding, int maxReadPoolSize, int maxWritePoolSize, XmlDictionaryReaderQuotas quotas, WebContentTypeMapper contentTypeMapper, bool javascriptCallbackEnabled)
        {
            messageEncoder = new WebMessageEncoder(writeEncoding, maxReadPoolSize, maxWritePoolSize, quotas, contentTypeMapper, javascriptCallbackEnabled);
        } 

        public override MessageEncoder Encoder 
        { 
            get { return messageEncoder; }
        } 

        public override MessageVersion MessageVersion
        {
            get { return messageEncoder.MessageVersion; } 
        }
 
        internal static string GetContentType(string mediaType, Encoding encoding) 
        {
            string charset = TextEncoderDefaults.EncodingToCharSet(encoding); 
            if (!string.IsNullOrEmpty(charset))
            {
                return string.Format(CultureInfo.InvariantCulture, "{0}; charset={1}", mediaType, charset);
            } 
            return mediaType;
        } 
 
        class WebMessageEncoder : MessageEncoder
        { 
            const string defaultMediaType = "application/xml";
            WebContentTypeMapper contentTypeMapper;
            string defaultContentType;
            MessageEncoder jsonMessageEncoder; 
            int maxReadPoolSize;
            int maxWritePoolSize; 
            MessageEncoder rawMessageEncoder; 
            XmlDictionaryReaderQuotas readerQuotas;
            MessageEncoder textMessageEncoder; 
            object thisLock;
            Encoding writeEncoding;
            bool javascriptCallbackEnabled;
 
            public WebMessageEncoder(Encoding writeEncoding, int maxReadPoolSize, int maxWritePoolSize, XmlDictionaryReaderQuotas quotas, WebContentTypeMapper contentTypeMapper, bool javascriptCallbackEnabled)
            { 
                if (writeEncoding == null) 
                {
                    throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("writeEncoding"); 
                }

                this.thisLock = new object();
 
                TextEncoderDefaults.ValidateEncoding(writeEncoding);
                this.writeEncoding = writeEncoding; 
 
                this.maxReadPoolSize = maxReadPoolSize;
                this.maxWritePoolSize = maxWritePoolSize; 
                this.contentTypeMapper = contentTypeMapper;
                this.javascriptCallbackEnabled = javascriptCallbackEnabled;

                this.readerQuotas = new XmlDictionaryReaderQuotas(); 
                quotas.CopyTo(this.readerQuotas);
 
                this.defaultContentType = GetContentType(defaultMediaType, writeEncoding); 
            }
 
            public override string ContentType
            {
                get { return this.defaultContentType; }
            } 

            public override string MediaType 
            { 
                get { return defaultMediaType; }
            } 

            public override MessageVersion MessageVersion
            {
                get { return MessageVersion.None; } 
            }
 
            MessageEncoder JsonMessageEncoder 
            {
                get 
                {
                    if (jsonMessageEncoder == null)
                    {
                        lock (ThisLock) 
                        {
                            if (jsonMessageEncoder == null) 
                            { 
                                jsonMessageEncoder = new JsonMessageEncoderFactory(writeEncoding, maxReadPoolSize, maxWritePoolSize, readerQuotas, javascriptCallbackEnabled).Encoder;
                            } 
                        }
                    }
                    return jsonMessageEncoder;
                } 
            }
 
            MessageEncoder RawMessageEncoder 
            {
                get 
                {
                    if (rawMessageEncoder == null)
                    {
                        lock (ThisLock) 
                        {
                            if (rawMessageEncoder == null) 
                            { 
                                rawMessageEncoder = new HttpStreamMessageEncoderFactory(readerQuotas).Encoder;
                            } 
                        }
                    }
                    return rawMessageEncoder;
                } 
            }
 
            MessageEncoder TextMessageEncoder 
            {
                get 
                {
                    if (textMessageEncoder == null)
                    {
                        lock (ThisLock) 
                        {
                            if (textMessageEncoder == null) 
                            { 
                                textMessageEncoder = new TextMessageEncoderFactory(MessageVersion.None, writeEncoding, maxReadPoolSize, maxWritePoolSize, readerQuotas).Encoder;
                            } 
                        }
                    }
                    return textMessageEncoder;
                } 
            }
 
            object ThisLock 
            {
                get { return thisLock; } 
            }

            public override bool IsContentTypeSupported(string contentType)
            { 
                if (contentType == null)
                { 
                    throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("contentType"); 
                }
 
                WebContentFormat messageFormat;
                if (TryGetContentTypeMapping(contentType, out messageFormat) &&
                    (messageFormat != WebContentFormat.Default))
                { 
                    return true;
                } 
 
                return RawMessageEncoder.IsContentTypeSupported(contentType) || JsonMessageEncoder.IsContentTypeSupported(contentType) || TextMessageEncoder.IsContentTypeSupported(contentType);
            } 

            public override Message ReadMessage(ArraySegment buffer, BufferManager bufferManager, string contentType)
            {
                if (bufferManager == null) 
                {
                    throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentNullException("bufferManager")); 
                } 

                WebContentFormat format = GetFormatForContentType(contentType); 
                Message message;

                switch (format)
                { 
                    case WebContentFormat.Json:
                        message = JsonMessageEncoder.ReadMessage(buffer, bufferManager, contentType); 
                        message.Properties.Add(WebBodyFormatMessageProperty.Name, WebBodyFormatMessageProperty.JsonProperty); 
                        break;
                    case WebContentFormat.Xml: 
                        message = TextMessageEncoder.ReadMessage(buffer, bufferManager, contentType);
                        message.Properties.Add(WebBodyFormatMessageProperty.Name, WebBodyFormatMessageProperty.XmlProperty);
                        break;
                    case WebContentFormat.Raw: 
                        message = RawMessageEncoder.ReadMessage(buffer, bufferManager, contentType);
                        message.Properties.Add(WebBodyFormatMessageProperty.Name, WebBodyFormatMessageProperty.RawProperty); 
                        break; 
                    default:
                        throw Fx.AssertAndThrow("This should never get hit because GetFormatForContentType shouldn't return a WebContentFormat other than Json, Xml, and Raw"); 
                }
                return message;
            }
 
            public override Message ReadMessage(Stream stream, int maxSizeOfHeaders, string contentType)
            { 
                if (stream == null) 
                {
                    throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentNullException("stream")); 
                }

                WebContentFormat format = GetFormatForContentType(contentType);
                Message message; 
                switch (format)
                { 
                    case WebContentFormat.Json: 
                        message = JsonMessageEncoder.ReadMessage(stream, maxSizeOfHeaders, contentType);
                        message.Properties.Add(WebBodyFormatMessageProperty.Name, WebBodyFormatMessageProperty.JsonProperty); 
                        break;
                    case WebContentFormat.Xml:
                        message = TextMessageEncoder.ReadMessage(stream, maxSizeOfHeaders, contentType);
                        message.Properties.Add(WebBodyFormatMessageProperty.Name, WebBodyFormatMessageProperty.XmlProperty); 
                        break;
                    case WebContentFormat.Raw: 
                        message = RawMessageEncoder.ReadMessage(stream, maxSizeOfHeaders, contentType); 
                        message.Properties.Add(WebBodyFormatMessageProperty.Name, WebBodyFormatMessageProperty.RawProperty);
                        break; 
                    default:
                        throw Fx.AssertAndThrow("This should never get hit because GetFormatForContentType shouldn't return a WebContentFormat other than Json, Xml, and Raw");
                }
                return message; 
            }
 
            public override ArraySegment WriteMessage(Message message, int maxMessageSize, BufferManager bufferManager, int messageOffset) 
            {
                if (message == null) 
                {
                    throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentNullException("message"));
                }
                if (bufferManager == null) 
                {
                    throw TraceUtility.ThrowHelperError(new ArgumentNullException("bufferManager"), message); 
                } 
                if (maxMessageSize < 0)
                { 
                    throw TraceUtility.ThrowHelperError(new ArgumentOutOfRangeException("maxMessageSize", maxMessageSize,
                        SR2.GetString(SR2.ValueMustBeNonNegative)), message);
                }
                if (messageOffset < 0 || messageOffset > maxMessageSize) 
                {
                    throw TraceUtility.ThrowHelperError(new ArgumentOutOfRangeException("messageOffset", messageOffset, 
                        SR2.GetString(SR2.JsonValueMustBeInRange, 0, maxMessageSize)), message); 
                }
                ThrowIfMismatchedMessageVersion(message); 

                WebContentFormat messageFormat = ExtractFormatFromMessage(message);
                JavascriptCallbackResponseMessageProperty javascriptResponseMessageProperty;
                switch (messageFormat) 
                {
                    case WebContentFormat.Json: 
                        return JsonMessageEncoder.WriteMessage(message, maxMessageSize, bufferManager, messageOffset); 
                    case WebContentFormat.Xml:
                        if (message.Properties.TryGetValue(JavascriptCallbackResponseMessageProperty.Name, out javascriptResponseMessageProperty) && 
                            javascriptResponseMessageProperty != null &&
                            !String.IsNullOrEmpty(javascriptResponseMessageProperty.CallbackFunctionName))
                        {
                            throw TraceUtility.ThrowHelperError(new InvalidOperationException(SR2.JavascriptCallbackNotsupported), message); 
                        }
                        return TextMessageEncoder.WriteMessage(message, maxMessageSize, bufferManager, messageOffset); 
                    case WebContentFormat.Raw: 
                        if (message.Properties.TryGetValue(JavascriptCallbackResponseMessageProperty.Name, out javascriptResponseMessageProperty) &&
                            javascriptResponseMessageProperty != null && 
                            !String.IsNullOrEmpty(javascriptResponseMessageProperty.CallbackFunctionName))
                        {
                            throw TraceUtility.ThrowHelperError(new InvalidOperationException(SR2.JavascriptCallbackNotsupported), message);
                        } 
                        return RawMessageEncoder.WriteMessage(message, maxMessageSize, bufferManager, messageOffset);
                    default: 
                        throw Fx.AssertAndThrow("This should never get hit because GetFormatForContentType shouldn't return a WebContentFormat other than Json, Xml, and Raw"); 
                }
            } 

            public override void WriteMessage(Message message, Stream stream)
            {
                if (message == null) 
                {
                    throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentNullException("message")); 
                } 
                if (stream == null)
                { 
                    throw TraceUtility.ThrowHelperError(new ArgumentNullException("stream"), message);
                }
                ThrowIfMismatchedMessageVersion(message);
 
                WebContentFormat messageFormat = ExtractFormatFromMessage(message);
                JavascriptCallbackResponseMessageProperty javascriptResponseMessageProperty; 
                switch (messageFormat) 
                {
                    case WebContentFormat.Json: 
                        JsonMessageEncoder.WriteMessage(message, stream);
                        break;
                    case WebContentFormat.Xml:
                        if (message.Properties.TryGetValue(JavascriptCallbackResponseMessageProperty.Name, out javascriptResponseMessageProperty) && 
                            javascriptResponseMessageProperty != null &&
                            !String.IsNullOrEmpty(javascriptResponseMessageProperty.CallbackFunctionName)) 
                        { 
                            throw TraceUtility.ThrowHelperError(new InvalidOperationException(SR2.JavascriptCallbackNotsupported), message);
                        } 
                        TextMessageEncoder.WriteMessage(message, stream);
                        break;
                    case WebContentFormat.Raw:
                        if (message.Properties.TryGetValue(JavascriptCallbackResponseMessageProperty.Name, out javascriptResponseMessageProperty) && 
                            javascriptResponseMessageProperty != null &&
                            !String.IsNullOrEmpty(javascriptResponseMessageProperty.CallbackFunctionName)) 
                        { 
                            throw TraceUtility.ThrowHelperError(new InvalidOperationException(SR2.JavascriptCallbackNotsupported), message);
                        } 
                        RawMessageEncoder.WriteMessage(message, stream);
                        break;
                    default:
                        throw Fx.AssertAndThrow("This should never get hit because GetFormatForContentType shouldn't return a WebContentFormat other than Json, Xml, and Raw"); 
                }
            } 
 
            internal override bool IsCharSetSupported(string charSet)
            { 
                Encoding tmp;
                return TextEncoderDefaults.TryGetEncoding(charSet, out tmp);
            }
 
            WebContentFormat ExtractFormatFromMessage(Message message)
            { 
                object messageFormatProperty; 
                message.Properties.TryGetValue(WebBodyFormatMessageProperty.Name, out messageFormatProperty);
                if (messageFormatProperty == null) 
                {
                    return WebContentFormat.Xml;
                }
 
                WebBodyFormatMessageProperty typedMessageFormatProperty = messageFormatProperty as WebBodyFormatMessageProperty;
                if ((typedMessageFormatProperty == null) || 
                    (typedMessageFormatProperty.Format == WebContentFormat.Default)) 
                {
                    return WebContentFormat.Xml; 
                }

                return typedMessageFormatProperty.Format;
            } 

            WebContentFormat GetFormatForContentType(string contentType) 
            { 
                WebContentFormat messageFormat;
 
                if (TryGetContentTypeMapping(contentType, out messageFormat) &&
                    (messageFormat != WebContentFormat.Default))
                {
                    if (DiagnosticUtility.ShouldTraceInformation) 
                    {
                        if (string.IsNullOrEmpty(contentType)) 
                        { 
                            contentType = "";
                        } 
                        TraceUtility.TraceEvent(TraceEventType.Information,
                            TraceCode.RequestFormatSelectedFromContentTypeMapper,
                            SR2.GetString(SR2.TraceCodeRequestFormatSelectedFromContentTypeMapper, messageFormat.ToString(), contentType));
                    } 
                    return messageFormat;
                } 
 
                // Don't pass on null content types to IsContentTypeSupported methods -- they might throw.
                // If null content type isn't already mapped, return the default format of Raw. 

                if (contentType == null)
                {
                    messageFormat = WebContentFormat.Raw; 
                }
                else if (JsonMessageEncoder.IsContentTypeSupported(contentType)) 
                { 
                    messageFormat = WebContentFormat.Json;
                } 
                else if (TextMessageEncoder.IsContentTypeSupported(contentType))
                {
                    messageFormat = WebContentFormat.Xml;
                } 
                else
                { 
                    messageFormat = WebContentFormat.Raw; 
                }
 
                if (DiagnosticUtility.ShouldTraceInformation)
                {
                    TraceUtility.TraceEvent(TraceEventType.Information,
                        TraceCode.RequestFormatSelectedByEncoderDefaults, 
                        SR2.GetString(SR2.TraceCodeRequestFormatSelectedByEncoderDefaults, messageFormat.ToString(), contentType));
                } 
 
                return messageFormat;
            } 

            bool TryGetContentTypeMapping(string contentType, out WebContentFormat format)
            {
                if (contentTypeMapper == null) 
                {
                    format = WebContentFormat.Default; 
                    return false; 
                }
 
                try
                {
                    format = contentTypeMapper.GetMessageFormatForContentType(contentType);
                    if (!WebContentFormatHelper.IsDefined(format)) 
                    {
                        throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentException(SR2.GetString(SR2.UnknownWebEncodingFormat, contentType, format))); 
                    } 
                    return true;
                } 
                catch (Exception e)
                {
                    if (Fx.IsFatal(e))
                    { 
                        throw;
                    } 
 
                    throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new CommunicationException(
                        SR2.GetString(SR2.ErrorEncounteredInContentTypeMapper), e)); 
                }
            }
        }
    } 
}

// File provided for Reference Use Only by Microsoft Corporation (c) 2007.


                        

Link Menu

Network programming in C#, Network Programming in VB.NET, Network Programming in .NET
This book is available now!
Buy at Amazon US or
Buy at Amazon UK