Example #1
0
        /// <summary>
        /// Returns an <see cref="Encoding"/> based on <paramref name="context"/>'s
        /// character set.
        /// </summary>
        /// <param name="context">The <see cref="InputFormatterContext"/>.</param>
        /// <returns>
        /// An <see cref="Encoding"/> based on <paramref name="context"/>'s
        /// character set. <c>null</c> if no supported encoding was found.
        /// </returns>
        protected Encoding SelectCharacterEncoding(InputFormatterContext context)
        {
            if (context == null)
            {
                throw new ArgumentNullException(nameof(context));
            }

            if (SupportedEncodings?.Count == 0)
            {
                var message = Resources.FormatTextInputFormatter_SupportedEncodingsMustNotBeEmpty(nameof(SupportedEncodings));
                throw new InvalidOperationException(message);
            }

            var request = context.HttpContext.Request;

            var requestEncoding = request.ContentType == null ? null : MediaType.GetEncoding(request.ContentType);

            if (requestEncoding != null)
            {
                for (int i = 0; i < SupportedEncodings.Count; i++)
                {
                    if (string.Equals(
                            requestEncoding.WebName,
                            SupportedEncodings[i].WebName,
                            StringComparison.OrdinalIgnoreCase))
                    {
                        return(SupportedEncodings[i]);
                    }
                }

                // The client specified an encoding in the content type header of the request
                // but we don't understand it. In this situation we don't try to pick any other encoding
                // from the list of supported encodings and read the body with that encoding.
                // Instead, we return null and that will translate later on into a 415 Unsupported Media Type
                // response.
                return(null);
            }

            // We want to do our best effort to read the body of the request even in the
            // cases where the client doesn't send a content type header or sends a content
            // type header without encoding. For that reason we pick the first encoding of the
            // list of supported encodings and try to use that to read the body. This encoding
            // is UTF-8 by default on our formatters, which generally is a safe choice for the
            // encoding.
            return(SupportedEncodings[0]);
        }
        /// <summary>
        /// Gets the content type and encoding that need to be used for the response.
        /// The priority for selecting the content type is:
        /// 1. ContentType property set on the action result
        /// 2. <see cref="HttpResponse.ContentType"/> property set on <see cref="HttpResponse"/>
        /// 3. Default content type set on the action result
        /// </summary>
        /// <remarks>
        /// The user supplied content type is not modified and is used as is. For example, if user
        /// sets the content type to be "text/plain" without any encoding, then the default content type's
        /// encoding is used to write the response and the ContentType header is set to be "text/plain" without any
        /// "charset" information.
        /// </remarks>
        /// <param name="actionResultContentType">ContentType set on the action result</param>
        /// <param name="httpResponseContentType"><see cref="HttpResponse.ContentType"/> property set
        /// on <see cref="HttpResponse"/></param>
        /// <param name="defaultContentType">The default content type of the action result.</param>
        /// <param name="resolvedContentType">The content type to be used for the response content type header</param>
        /// <param name="resolvedContentTypeEncoding">Encoding to be used for writing the response</param>
        public static void ResolveContentTypeAndEncoding(
            string actionResultContentType,
            string httpResponseContentType,
            string defaultContentType,
            out string resolvedContentType,
            out Encoding resolvedContentTypeEncoding)
        {
            Debug.Assert(defaultContentType != null);

            var defaultContentTypeEncoding = MediaType.GetEncoding(defaultContentType);

            Debug.Assert(defaultContentTypeEncoding != null);

            // 1. User sets the ContentType property on the action result
            if (actionResultContentType != null)
            {
                resolvedContentType = actionResultContentType;
                var actionResultEncoding = MediaType.GetEncoding(actionResultContentType);
                resolvedContentTypeEncoding = actionResultEncoding ?? defaultContentTypeEncoding;
                return;
            }

            // 2. User sets the ContentType property on the http response directly
            if (!string.IsNullOrEmpty(httpResponseContentType))
            {
                var mediaTypeEncoding = MediaType.GetEncoding(httpResponseContentType);
                if (mediaTypeEncoding != null)
                {
                    resolvedContentType         = httpResponseContentType;
                    resolvedContentTypeEncoding = mediaTypeEncoding;
                }
                else
                {
                    resolvedContentType         = httpResponseContentType;
                    resolvedContentTypeEncoding = defaultContentTypeEncoding;
                }

                return;
            }

            // 3. Fall-back to the default content type
            resolvedContentType         = defaultContentType;
            resolvedContentTypeEncoding = defaultContentTypeEncoding;
        }