/// <summary>
        /// Determines the best <see cref="Encoding"/> amongst the supported encodings
        /// for reading or writing an HTTP entity body based on the provided <paramref name="contentHeaders"/>.
        /// </summary>
        /// <param name="contentHeaders">The content headers provided as part of the request or response.</param>
        /// <returns>The <see cref="Encoding"/> to use when reading the request or writing the response.</returns>
        protected Encoding SelectCharacterEncoding(HttpContentHeaders contentHeaders)
        {
            Encoding encoding = null;

            if (contentHeaders != null && contentHeaders.ContentType != null)
            {
                // Find encoding based on content type charset parameter
                string charset = contentHeaders.ContentType.CharSet;
                if (!String.IsNullOrWhiteSpace(charset))
                {
                    encoding =
                        SupportedEncodings.FirstOrDefault(
                            enc => charset.Equals(enc.WebName, StringComparison.OrdinalIgnoreCase));
                }
            }

            if (encoding == null)
            {
                // We didn't find a character encoding match based on the content headers.
                // Instead we try getting the default character encoding.
                encoding = SupportedEncodings.FirstOrDefault();
            }

            if (encoding == null)
            {
                // No supported encoding was found so there is no way for us to start reading or writing.
                throw new InvalidOperationException(RS.Format(Properties.Resources.MediaTypeFormatterNoEncoding, GetType().Name));
            }

            return(encoding);
        }
예제 #2
0
        private Encoding MatchAcceptCharacterEncoding(IList <StringWithQualityHeaderValue> acceptCharsetHeaders)
        {
            if (acceptCharsetHeaders != null && acceptCharsetHeaders.Count > 0)
            {
                var sortedAcceptCharsetHeaders = acceptCharsetHeaders
                                                 .Where(acceptCharset =>
                                                        acceptCharset.Quality != HeaderQuality.NoMatch)
                                                 .OrderByDescending(
                    m => m, StringWithQualityHeaderValueComparer.QualityComparer);

                foreach (var acceptCharset in sortedAcceptCharsetHeaders)
                {
                    var charset = acceptCharset.Value;
                    if (!string.IsNullOrWhiteSpace(charset))
                    {
                        var encoding = SupportedEncodings.FirstOrDefault(
                            supportedEncoding =>
                            charset.Equals(supportedEncoding.WebName,
                                           StringComparison.OrdinalIgnoreCase) ||
                            charset.Equals("*", StringComparison.Ordinal));
                        if (encoding != null)
                        {
                            return(encoding);
                        }
                    }
                }
            }

            return(null);
        }
        public override async Task <object> ReadFromStreamAsync(Type type, Stream readStream, HttpContent content, IFormatterLogger formatterLogger)
        {
            var instance = await Task.Run(() =>
            {
                var serializer = JsonSerializer.Create(SerializerSettings);
                using (var streamReader = new StreamReader(readStream, SupportedEncodings.FirstOrDefault() ?? new UTF8Encoding()))
                    using (var jsonTextReader = new JsonTextReader(streamReader))
                        return(serializer.Deserialize(jsonTextReader));
            });

            return(instance);
        }
예제 #4
0
        /// <summary>
        /// Determines the best <see cref="Encoding"/> amongst the supported encodings
        /// for reading or writing an HTTP entity body based on the provided <paramref name="contentTypeHeader"/>.
        /// </summary>
        /// <param name="context">The formatter context associated with the call.
        /// </param>
        /// <returns>The <see cref="Encoding"/> to use when reading the request or writing the response.</returns>
        public virtual Encoding SelectCharacterEncoding(OutputFormatterContext context)
        {
            var request  = context.ActionContext.HttpContext.Request;
            var encoding = MatchAcceptCharacterEncoding(request.AcceptCharset);

            if (encoding == null)
            {
                // Match based on request acceptHeader.
                var requestContentType = MediaTypeHeaderValue.Parse(request.ContentType);
                if (requestContentType != null && !string.IsNullOrEmpty(requestContentType.Charset))
                {
                    var requestCharset = requestContentType.Charset;
                    encoding = SupportedEncodings.FirstOrDefault(
                        supportedEncoding =>
                        requestCharset.Equals(supportedEncoding.WebName));
                }
            }

            encoding = encoding ?? SupportedEncodings.FirstOrDefault();
            return(encoding);
        }
        /// <summary>
        /// Sets the default headers for content that will be formatted using this formatter. This method
        /// is called from the <see cref="ObjectContent"/> constructor.
        /// This implementation sets the Content-Type header to the value of <paramref name="mediaType"/> if it is
        /// not <c>null</c>. If it is <c>null</c> it sets the Content-Type to the default media type of this formatter.
        /// If the Content-Type does not specify a charset it will set it using this formatters configured
        /// <see cref="Encoding"/>.
        /// </summary>
        /// <remarks>
        /// Subclasses can override this method to set content headers such as Content-Type etc. Subclasses should
        /// call the base implementation. Subclasses should treat the passed in <paramref name="mediaType"/> (if not <c>null</c>)
        /// as the authoritative media type and use that as the Content-Type.
        /// </remarks>
        /// <param name="type">The type of the object being serialized. See <see cref="ObjectContent"/>.</param>
        /// <param name="headers">The content headers that should be configured.</param>
        /// <param name="mediaType">The authoritative media type. Can be <c>null</c>.</param>
        public virtual void SetDefaultContentHeaders(Type type, HttpContentHeaders headers, string mediaType)
        {
            if (type == null)
            {
                throw new ArgumentNullException("type");
            }
            if (headers == null)
            {
                throw new ArgumentNullException("headers");
            }

            if (!String.IsNullOrEmpty(mediaType))
            {
                var parsedMediaType = MediaTypeHeaderValue.Parse(mediaType);
                headers.ContentType = parsedMediaType;
            }

            // If content type is not set then set it based on supported media types.
            if (headers.ContentType == null)
            {
                MediaTypeHeaderValue defaultMediaType = SupportedMediaTypes.FirstOrDefault();
                if (defaultMediaType != null)
                {
                    headers.ContentType = defaultMediaType.Clone();
                }
            }

            // If content type charset parameter is not set then set it based on the supported encodings.
            if (headers.ContentType != null && headers.ContentType.CharSet == null)
            {
                Encoding defaultEncoding = SupportedEncodings.FirstOrDefault();
                if (defaultEncoding != null)
                {
                    headers.ContentType.CharSet = defaultEncoding.WebName;
                }
            }
        }
        /// <summary>
        /// Sets the default headers for content that will be formatted using this formatter. This method
        /// is called from the <see cref="ObjectContent"/> constructor.
        /// This implementation sets the Content-Type header to the value of <paramref name="mediaType"/> if it is
        /// not <c>null</c>. If it is <c>null</c> it sets the Content-Type to the default media type of this formatter.
        /// If the Content-Type does not specify a charset it will set it using this formatters configured
        /// <see cref="Encoding"/>.
        /// </summary>
        /// <remarks>
        /// Subclasses can override this method to set content headers such as Content-Type etc. Subclasses should
        /// call the base implementation. Subclasses should treat the passed in <paramref name="mediaType"/> (if not <c>null</c>)
        /// as the authoritative media type and use that as the Content-Type.
        /// </remarks>
        /// <param name="type">The type of the object being serialized. See <see cref="ObjectContent"/>.</param>
        /// <param name="headers">The content headers that should be configured.</param>
        /// <param name="mediaType">The authoritative media type. Can be <c>null</c>.</param>
        public virtual void SetDefaultContentHeaders(Type type, HttpContentHeaders headers, MediaTypeHeaderValue mediaType)
        {
            if (type == null)
            {
                throw Error.ArgumentNull("type");
            }
            if (headers == null)
            {
                throw Error.ArgumentNull("headers");
            }

            if (mediaType != null)
            {
                headers.ContentType = mediaType.Clone();
            }

            // If content type is not set then set it based on supported media types.
            if (headers.ContentType == null)
            {
                MediaTypeHeaderValue defaultMediaType = SupportedMediaTypes.FirstOrDefault();
                if (defaultMediaType != null)
                {
                    headers.ContentType = defaultMediaType.Clone();
                }
            }

            // If content type charset parameter is not set then set it based on the supported encodings.
            if (headers.ContentType != null && headers.ContentType.CharSet == null)
            {
                Encoding defaultEncoding = SupportedEncodings.FirstOrDefault();
                if (defaultEncoding != null)
                {
                    headers.ContentType.CharSet = defaultEncoding.WebName;
                }
            }
        }