Ejemplo n.º 1
0
        /// <summary>
        /// Determine the <see cref="ODataFormat"/> to use for the given <paramref name="contentTypeHeader"/>. If no supported content type
        /// is found an exception is thrown.
        /// </summary>
        /// <param name="contentTypeHeader">The name of the content type to be checked.</param>
        /// <param name="supportedPayloadKinds">All possiblel kinds of payload that can be read with this content type.</param>
        /// <param name="mediaTypeResolver">The media type resolver to use when interpreting the content type.</param>
        /// <param name="mediaType">The media type parsed from the <paramref name="contentTypeHeader"/>.</param>
        /// <param name="encoding">The encoding from the content type or the default encoding for the <paramref name="mediaType" />.</param>
        /// <param name="selectedPayloadKind">
        /// The payload kind that was selected form the list of <paramref name="supportedPayloadKinds"/> for the
        /// specified <paramref name="contentTypeHeader"/>.
        /// </param>
        /// <param name="batchBoundary">The batch boundary read from the content type for batch payloads; otherwise null.</param>
        /// <returns>The <see cref="ODataFormat"/> for the <paramref name="contentTypeHeader"/>.</returns>
        internal static ODataFormat GetFormatFromContentType(
            string contentTypeHeader,
            ODataPayloadKind[] supportedPayloadKinds,
            MediaTypeResolver mediaTypeResolver,
            out MediaType mediaType,
            out Encoding encoding,
            out ODataPayloadKind selectedPayloadKind,
            out string batchBoundary)
        {
            DebugUtils.CheckNoExternalCallers();
            Debug.Assert(!supportedPayloadKinds.Contains(ODataPayloadKind.Unsupported), "!supportedPayloadKinds.Contains(ODataPayloadKind.Unsupported)");

            ODataFormat format = GetFormatFromContentType(contentTypeHeader, supportedPayloadKinds, mediaTypeResolver, out mediaType, out encoding, out selectedPayloadKind);

            // for batch payloads, read the batch boundary from the content type header; this is the only
            // content type parameter we support (and that is required for batch payloads)
            if (selectedPayloadKind == ODataPayloadKind.Batch)
            {
                KeyValuePair <string, string> boundaryPair = default(KeyValuePair <string, string>);
                IEnumerable <KeyValuePair <string, string> > parameters = mediaType.Parameters;
                if (parameters != null)
                {
                    bool boundaryPairFound = false;
                    foreach (KeyValuePair <string, string> pair in parameters.Where(p => HttpUtils.CompareMediaTypeParameterNames(ODataConstants.HttpMultipartBoundary, p.Key)))
                    {
                        if (boundaryPairFound)
                        {
                            throw new ODataException(Strings.MediaTypeUtils_BoundaryMustBeSpecifiedForBatchPayloads(contentTypeHeader, ODataConstants.HttpMultipartBoundary));
                        }

                        boundaryPair      = pair;
                        boundaryPairFound = true;
                    }
                }

                if (boundaryPair.Key == null)
                {
                    throw new ODataException(Strings.MediaTypeUtils_BoundaryMustBeSpecifiedForBatchPayloads(contentTypeHeader, ODataConstants.HttpMultipartBoundary));
                }

                batchBoundary = boundaryPair.Value;
                ValidationUtils.ValidateBoundaryString(batchBoundary);
            }
            else
            {
                batchBoundary = null;
            }

            return(format);
        }
Ejemplo n.º 2
0
        /// <summary>
        /// Determine the <see cref="ODataFormat"/> to use for the given <paramref name="contentTypeName"/>. If no supported content type
        /// is found an exception is thrown.
        /// </summary>
        /// <param name="contentTypeName">The name of the content type to be checked.</param>
        /// <param name="supportedPayloadKinds">All possiblel kinds of payload that can be read with this content type.</param>
        /// <param name="mediaTypeResolver">The media type resolver to use when interpreting the content type.</param>
        /// <param name="mediaType">The media type parsed from the <paramref name="contentTypeName"/>.</param>
        /// <param name="encoding">The encoding from the content type or the default encoding for the <paramref name="mediaType" />.</param>
        /// <param name="selectedPayloadKind">
        /// The payload kind that was selected form the list of <paramref name="supportedPayloadKinds"/> for the
        /// specified <paramref name="contentTypeName"/>.
        /// </param>
        /// <returns>The <see cref="ODataFormat"/> for the <paramref name="contentTypeName"/>.</returns>
        private static ODataFormat GetFormatFromContentType(
            string contentTypeName,
            ODataPayloadKind[] supportedPayloadKinds,
            MediaTypeResolver mediaTypeResolver,
            out MediaType mediaType,
            out Encoding encoding,
            out ODataPayloadKind selectedPayloadKind)
        {
            Debug.Assert(!supportedPayloadKinds.Contains(ODataPayloadKind.Unsupported), "!supportedPayloadKinds.Contains(ODataPayloadKind.Unsupported)");

            string charset;

            mediaType = ParseContentType(contentTypeName, out charset);

            // Special code to handle unsupported media types that cannot be caught by conneg
            // since they are sub-types of valid media types (i.e., application/json;odata=light would
            // match application/json).
            // NOTE: once we start supporting Json Light we have to make this check version-aware.
            FailOnUnsupportedMediaTypes(mediaType, contentTypeName, supportedPayloadKinds, mediaTypeResolver);

            MediaTypeWithFormat[] supportedMediaTypes = null;
            for (int i = 0; i < supportedPayloadKinds.Length; ++i)
            {
                // get the supported and default media types for the current payload kind
                ODataPayloadKind supportedPayloadKind = supportedPayloadKinds[i];
                supportedMediaTypes = mediaTypeResolver.GetMediaTypesForPayloadKind(supportedPayloadKind);

                // match the specified media types against the supported/default ones
                // and get the format
                MediaTypeMatchInfo matchInfo = MatchMediaTypes(supportedMediaTypes.Select(smt => smt.MediaType), new MediaType[] { mediaType });
                if (matchInfo != null)
                {
                    Debug.Assert(matchInfo.TargetTypeIndex == 0, "Invalid target type index detected.");
                    selectedPayloadKind = supportedPayloadKind;
                    encoding            = GetEncoding(charset, selectedPayloadKind, mediaType, /*useDefaultEncoding*/ false);
                    return(supportedMediaTypes[matchInfo.SourceTypeIndex].Format);
                }
            }

            // We're calling the ToArray here since not all platforms support the string.Join which takes IEnumerable.
            Debug.Assert(supportedMediaTypes != null, "supportedMediaTypes != null");
            string supportedTypesAsString = string.Join(", ", supportedPayloadKinds.SelectMany(pk => mediaTypeResolver.GetMediaTypesForPayloadKind(pk).Select(mt => mt.MediaType.ToText())).ToArray());

            throw new ODataContentTypeException(Strings.MediaTypeUtils_CannotDetermineFormatFromContentType(supportedTypesAsString, contentTypeName));
        }
Ejemplo n.º 3
0
        /// <summary>
        /// Given the Accept and the Accept-Charset headers of the request message computes the media type, encoding and <see cref="ODataFormat"/>
        /// to be used for the response message.
        /// </summary>
        /// <param name="settings">The message writer settings to use for serializing the response payload.</param>
        /// <param name="payloadKind">The kind of payload to be serialized as part of the response message.</param>
        /// <param name="mediaTypeResolver">The media type resolver to use when interpreting the content type.</param>
        /// <param name="mediaType">The media type to be used in the response message.</param>
        /// <param name="encoding">The encoding to be used in the response message.</param>
        /// <returns>The <see cref="ODataFormat"/> used when serializing the response.</returns>
        internal static ODataFormat GetContentTypeFromSettings(
            ODataMessageWriterSettings settings,
            ODataPayloadKind payloadKind,
            MediaTypeResolver mediaTypeResolver,
            out MediaType mediaType,
            out Encoding encoding)
        {
            DebugUtils.CheckNoExternalCallers();
            Debug.Assert(settings != null, "settings != null");

            // compute format, media type and encoding
            ODataFormat format;

            // get the supported and default media types for the specified payload kind
            MediaTypeWithFormat[] supportedMediaTypes = mediaTypeResolver.GetMediaTypesForPayloadKind(payloadKind);
            if (supportedMediaTypes == null || supportedMediaTypes.Length == 0)
            {
                throw new ODataContentTypeException(Strings.MediaTypeUtils_DidNotFindMatchingMediaType(null, settings.AcceptableMediaTypes));
            }

            if (settings.UseFormat == true)
            {
                Debug.Assert(settings.AcceptableMediaTypes == null, "settings.AcceptableMediaTypes == null");
                Debug.Assert(settings.AcceptableCharsets == null, "settings.AcceptableCharsets == null");

                mediaType = GetDefaultMediaType(supportedMediaTypes, settings.Format, out format);

                // NOTE the default media types don't have any parameters (in particular no 'charset' parameters)
                encoding = mediaType.SelectEncoding();
            }
            else
            {
                // parse the accept header into its parts
                IList <KeyValuePair <MediaType, string> > specifiedTypes = HttpUtils.MediaTypesFromString(settings.AcceptableMediaTypes);

                if (settings.Version == ODataVersion.V3)
                {
                    specifiedTypes = RemoveApplicationJsonFromAcceptableMediaTypes(specifiedTypes, supportedMediaTypes, settings.AcceptableMediaTypes);
                }

                MediaTypeWithFormat selectedMediaTypeWithFormat;
                string specifiedCharset = null;
                if (specifiedTypes == null || specifiedTypes.Count == 0)
                {
                    selectedMediaTypeWithFormat = supportedMediaTypes[0];
                }
                else
                {
                    // match the specified media types against the supported/default ones and get the format
                    MediaTypeMatchInfo matchInfo = MatchMediaTypes(specifiedTypes.Select(kvp => kvp.Key), supportedMediaTypes.Select(smt => smt.MediaType).ToArray());
                    if (matchInfo == null)
                    {
                        // We're calling the ToArray here since not all platforms support the string.Join which takes IEnumerable.
                        string supportedTypesAsString = string.Join(", ", supportedMediaTypes.Select(mt => mt.MediaType.ToText()).ToArray());
                        throw new ODataContentTypeException(Strings.MediaTypeUtils_DidNotFindMatchingMediaType(supportedTypesAsString, settings.AcceptableMediaTypes));
                    }

                    selectedMediaTypeWithFormat = supportedMediaTypes[matchInfo.TargetTypeIndex];
                    specifiedCharset            = specifiedTypes[matchInfo.SourceTypeIndex].Value;
                }

                format    = selectedMediaTypeWithFormat.Format;
                mediaType = selectedMediaTypeWithFormat.MediaType;

                // If a charset was specified with the accept header, consider it for the encoding
                string acceptableCharsets = settings.AcceptableCharsets;
                if (specifiedCharset != null)
                {
                    acceptableCharsets = acceptableCharsets == null ? specifiedCharset : specifiedCharset + "," + acceptableCharsets;
                }

                encoding = GetEncoding(acceptableCharsets, payloadKind, mediaType, /*useDefaultEncoding*/ true);
            }

            return(format);
        }
Ejemplo n.º 4
0
 /// <summary>
 /// Fails early on unsupported content types that cannot be caught by content negotiation/resolution.
 /// </summary>
 /// <param name="contentType">The parsed media type from the <paramref name="contentTypeName"/>.</param>
 /// <param name="contentTypeName">The name of the content type to be checked (for error reporting only).</param>
 /// <param name="supportedPayloadKinds">All possible kinds of payload that can be read with this content type (for error reporting only).</param>
 /// <param name="mediaTypeResolver">The media type resolver to use when interpreting the content type (for error reporting only).</param>
 private static void FailOnUnsupportedMediaTypes(MediaType contentType, string contentTypeName, ODataPayloadKind[] supportedPayloadKinds, MediaTypeResolver mediaTypeResolver)
 {
     // We currently fail for application/json;odata=light for all version.
     // Once we support Json Light, we will only fail for V1 and V2 where Json Light continues to not be supported.
     // NOTE: once we support custom formats and custom content negotiation, we will have to move this logic into
     //       the format itself (i.e., also register Json Light for V1 and V2 but make it fail).
     if (HttpUtils.CompareMediaTypeNames(contentType.SubTypeName, MimeConstants.MimeJsonSubType) &&
         HttpUtils.CompareMediaTypeNames(contentType.TypeName, MimeConstants.MimeApplicationType) &&
         contentType.Parameters != null &&
         contentType.Parameters.Where(p =>
                                      HttpUtils.CompareMediaTypeParameterNames(p.Key, MimeConstants.MimeODataParameterName) &&
                                      string.Compare(MimeConstants.MimeODataParameterValueLight, p.Value, StringComparison.OrdinalIgnoreCase) == 0).Any())
     {
         string supportedTypesAsString = string.Join(", ", supportedPayloadKinds.SelectMany(pk => mediaTypeResolver.GetMediaTypesForPayloadKind(pk).Select(mt => mt.MediaType.ToText())).ToArray());
         throw new ODataContentTypeException(Strings.MediaTypeUtils_CannotDetermineFormatFromContentType(supportedTypesAsString, contentTypeName));
     }
 }
Ejemplo n.º 5
0
        /// <summary>
        /// Gets all payload kinds and their corresponding formats that match the specified content type header.
        /// </summary>
        /// <param name="contentTypeHeader">The content type header to get the payload kinds for.</param>
        /// <param name="mediaTypeResolver">The media type resolver to use when interpreting the content type.</param>
        /// <param name="contentType">The parsed content type as <see cref="MediaType"/>.</param>
        /// <param name="encoding">The encoding from the content type or the default encoding from <see cref="MediaType" />.</param>
        /// <returns>The list of payload kinds and formats supported for the specified <paramref name="contentTypeHeader"/>.</returns>
        internal static IList <ODataPayloadKindDetectionResult> GetPayloadKindsForContentType(string contentTypeHeader, MediaTypeResolver mediaTypeResolver, out MediaType contentType, out Encoding encoding)
        {
            DebugUtils.CheckNoExternalCallers();
            Debug.Assert(!string.IsNullOrEmpty(contentTypeHeader), "Content-Type header must not be null or empty.");

            string charset;

            encoding    = null;
            contentType = ParseContentType(contentTypeHeader, out charset);
            MediaType[] targetTypes = new MediaType[] { contentType };

            List <ODataPayloadKindDetectionResult> payloadKinds = new List <ODataPayloadKindDetectionResult>();

            MediaTypeWithFormat[] mediaTypesForKind = null;
            for (int i = 0; i < allSupportedPayloadKinds.Length; ++i)
            {
                // get the supported and default media types for the current payload kind
                ODataPayloadKind payloadKind = allSupportedPayloadKinds[i];
                mediaTypesForKind = mediaTypeResolver.GetMediaTypesForPayloadKind(payloadKind);

                // match the specified media types against the supported/default ones
                // and get the format
                MediaTypeMatchInfo matchInfo = MatchMediaTypes(mediaTypesForKind.Select(smt => smt.MediaType), targetTypes);
                if (matchInfo != null)
                {
                    Debug.Assert(matchInfo.TargetTypeIndex == 0, "Invalid target type index detected.");
                    payloadKinds.Add(new ODataPayloadKindDetectionResult(payloadKind, mediaTypesForKind[matchInfo.SourceTypeIndex].Format));
                }
            }

            if (!string.IsNullOrEmpty(charset))
            {
                encoding = HttpUtils.GetEncodingFromCharsetName(charset);
            }

            return(payloadKinds);
        }
Ejemplo n.º 6
0
        internal static ODataFormat GetContentTypeFromSettings(ODataMessageWriterSettings settings, ODataPayloadKind payloadKind, MediaTypeResolver mediaTypeResolver, out MediaType mediaType, out Encoding encoding)
        {
            ODataFormat         format;
            MediaTypeWithFormat format2;

            MediaTypeWithFormat[] mediaTypesForPayloadKind = mediaTypeResolver.GetMediaTypesForPayloadKind(payloadKind);
            if ((mediaTypesForPayloadKind == null) || (mediaTypesForPayloadKind.Length == 0))
            {
                throw new ODataContentTypeException(Microsoft.Data.OData.Strings.MediaTypeUtils_DidNotFindMatchingMediaType(null, settings.AcceptableMediaTypes));
            }
            if (settings.UseFormat == true)
            {
                mediaType = GetDefaultMediaType(mediaTypesForPayloadKind, settings.Format, out format);
                encoding  = mediaType.SelectEncoding();
                return(format);
            }
            IList <KeyValuePair <MediaType, string> > specifiedTypes = HttpUtils.MediaTypesFromString(settings.AcceptableMediaTypes);

            if (((ODataVersion)settings.Version) == ODataVersion.V3)
            {
                specifiedTypes = RemoveApplicationJsonFromAcceptableMediaTypes(specifiedTypes, mediaTypesForPayloadKind, settings.AcceptableMediaTypes);
            }
            string str = null;

            if ((specifiedTypes == null) || (specifiedTypes.Count == 0))
            {
                format2 = mediaTypesForPayloadKind[0];
            }
            else
            {
                MediaTypeMatchInfo info = MatchMediaTypes(from kvp in specifiedTypes select kvp.Key, (from smt in mediaTypesForPayloadKind select smt.MediaType).ToArray <MediaType>());
                if (info == null)
                {
                    throw new ODataContentTypeException(Microsoft.Data.OData.Strings.MediaTypeUtils_DidNotFindMatchingMediaType(string.Join(", ", (from mt in mediaTypesForPayloadKind select mt.MediaType.ToText()).ToArray <string>()), settings.AcceptableMediaTypes));
                }
                format2 = mediaTypesForPayloadKind[info.TargetTypeIndex];
                KeyValuePair <MediaType, string> pair = specifiedTypes[info.SourceTypeIndex];
                str = pair.Value;
            }
            format    = format2.Format;
            mediaType = format2.MediaType;
            string acceptableCharsets = settings.AcceptableCharsets;

            if (str != null)
            {
                acceptableCharsets = (acceptableCharsets == null) ? str : (str + "," + acceptableCharsets);
            }
            encoding = GetEncoding(acceptableCharsets, payloadKind, mediaType, true);
            return(format);
        }
Ejemplo n.º 7
0
        private static void FailOnUnsupportedMediaTypes(MediaType contentType, string contentTypeName, ODataPayloadKind[] supportedPayloadKinds, MediaTypeResolver mediaTypeResolver)
        {
            Func <ODataPayloadKind, IEnumerable <string> > selector = null;

            if (((HttpUtils.CompareMediaTypeNames(contentType.SubTypeName, "json") && HttpUtils.CompareMediaTypeNames(contentType.TypeName, "application")) && (contentType.Parameters != null)) && (from p in contentType.Parameters
                                                                                                                                                                                                     where HttpUtils.CompareMediaTypeParameterNames(p.Key, "odata") && (string.Compare("light", p.Value, StringComparison.OrdinalIgnoreCase) == 0)
                                                                                                                                                                                                     select p).Any <KeyValuePair <string, string> >())
            {
                if (selector == null)
                {
                    selector = pk => from mt in mediaTypeResolver.GetMediaTypesForPayloadKind(pk) select mt.MediaType.ToText();
                }
                throw new ODataContentTypeException(Microsoft.Data.OData.Strings.MediaTypeUtils_CannotDetermineFormatFromContentType(string.Join(", ", supportedPayloadKinds.SelectMany <ODataPayloadKind, string>(selector).ToArray <string>()), contentTypeName));
            }
        }
Ejemplo n.º 8
0
        internal static IList <ODataPayloadKindDetectionResult> GetPayloadKindsForContentType(string contentTypeHeader, MediaTypeResolver mediaTypeResolver, out MediaType contentType)
        {
            string str;

            contentType = ParseContentType(contentTypeHeader, out str);
            MediaType[] targetTypes = new MediaType[] { contentType };
            List <ODataPayloadKindDetectionResult> list = new List <ODataPayloadKindDetectionResult>();

            MediaTypeWithFormat[] mediaTypesForPayloadKind = null;
            for (int i = 0; i < allSupportedPayloadKinds.Length; i++)
            {
                ODataPayloadKind payloadKind = allSupportedPayloadKinds[i];
                mediaTypesForPayloadKind = mediaTypeResolver.GetMediaTypesForPayloadKind(payloadKind);
                MediaTypeMatchInfo info = MatchMediaTypes(from smt in mediaTypesForPayloadKind select smt.MediaType, targetTypes);
                if (info != null)
                {
                    list.Add(new ODataPayloadKindDetectionResult(payloadKind, mediaTypesForPayloadKind[info.SourceTypeIndex].Format));
                }
            }
            return(list);
        }
Ejemplo n.º 9
0
        internal static ODataFormat GetFormatFromContentType(string contentTypeHeader, ODataPayloadKind[] supportedPayloadKinds, MediaTypeResolver mediaTypeResolver, out MediaType mediaType, out Encoding encoding, out ODataPayloadKind selectedPayloadKind, out string batchBoundary)
        {
            ODataFormat format = GetFormatFromContentType(contentTypeHeader, supportedPayloadKinds, mediaTypeResolver, out mediaType, out encoding, out selectedPayloadKind);

            if (selectedPayloadKind == ODataPayloadKind.Batch)
            {
                KeyValuePair <string, string> pair = new KeyValuePair <string, string>();
                IEnumerable <KeyValuePair <string, string> > parameters = mediaType.Parameters;
                if (parameters != null)
                {
                    bool flag = false;
                    foreach (KeyValuePair <string, string> pair2 in from p in parameters
                             where HttpUtils.CompareMediaTypeParameterNames("boundary", p.Key)
                             select p)
                    {
                        if (flag)
                        {
                            throw new ODataException(Microsoft.Data.OData.Strings.MediaTypeUtils_BoundaryMustBeSpecifiedForBatchPayloads(contentTypeHeader, "boundary"));
                        }
                        pair = pair2;
                        flag = true;
                    }
                }
                if (pair.Key == null)
                {
                    throw new ODataException(Microsoft.Data.OData.Strings.MediaTypeUtils_BoundaryMustBeSpecifiedForBatchPayloads(contentTypeHeader, "boundary"));
                }
                batchBoundary = pair.Value;
                ValidationUtils.ValidateBoundaryString(batchBoundary);
                return(format);
            }
            batchBoundary = null;
            return(format);
        }
Ejemplo n.º 10
0
        private static ODataFormat GetFormatFromContentType(string contentTypeName, ODataPayloadKind[] supportedPayloadKinds, MediaTypeResolver mediaTypeResolver, out MediaType mediaType, out Encoding encoding, out ODataPayloadKind selectedPayloadKind)
        {
            string str;

            mediaType = ParseContentType(contentTypeName, out str);
            FailOnUnsupportedMediaTypes(mediaType, contentTypeName, supportedPayloadKinds, mediaTypeResolver);
            MediaTypeWithFormat[] mediaTypesForPayloadKind = null;
            for (int i = 0; i < supportedPayloadKinds.Length; i++)
            {
                ODataPayloadKind payloadKind = supportedPayloadKinds[i];
                mediaTypesForPayloadKind = mediaTypeResolver.GetMediaTypesForPayloadKind(payloadKind);
                MediaTypeMatchInfo info = MatchMediaTypes(from smt in mediaTypesForPayloadKind select smt.MediaType, new MediaType[] { mediaType });
                if (info != null)
                {
                    selectedPayloadKind = payloadKind;
                    encoding            = GetEncoding(str, selectedPayloadKind, mediaType, false);
                    return(mediaTypesForPayloadKind[info.SourceTypeIndex].Format);
                }
            }
            throw new ODataContentTypeException(Microsoft.Data.OData.Strings.MediaTypeUtils_CannotDetermineFormatFromContentType(string.Join(", ", (from pk in supportedPayloadKinds select from mt in mediaTypeResolver.GetMediaTypesForPayloadKind(pk) select mt.MediaType.ToText()).SelectMany(x => x).ToArray <string>()), contentTypeName));
        }
Ejemplo n.º 11
0
        /// <summary>
        /// Given the Accept and the Accept-Charset headers of the request message computes the media type, encoding and <see cref="ODataFormat"/>
        /// to be used for the response message.
        /// </summary>
        /// <param name="settings">The message writer settings to use for serializing the response payload.</param>
        /// <param name="payloadKind">The kind of payload to be serialized as part of the response message.</param>
        /// <param name="mediaTypeResolver">The media type resolver to use when interpreting the content type.</param>
        /// <param name="mediaType">The media type to be used in the response message.</param>
        /// <param name="encoding">The encoding to be used in the response message.</param>
        /// <returns>The <see cref="ODataFormat"/> used when serializing the response.</returns>
        internal static ODataFormat GetContentTypeFromSettings(
            ODataMessageWriterSettings settings,
            ODataPayloadKind payloadKind,
            MediaTypeResolver mediaTypeResolver,
            out MediaType mediaType,
            out Encoding encoding)
        {
            DebugUtils.CheckNoExternalCallers();
            Debug.Assert(settings != null, "settings != null");

            // compute format, media type and encoding
            ODataFormat format;

            // get the supported and default media types for the specified payload kind
            IList <MediaTypeWithFormat> supportedMediaTypes = mediaTypeResolver.GetMediaTypesForPayloadKind(payloadKind);

            if (supportedMediaTypes == null || supportedMediaTypes.Count == 0)
            {
                throw new ODataContentTypeException(Strings.MediaTypeUtils_DidNotFindMatchingMediaType(null, settings.AcceptableMediaTypes));
            }

            if (settings.UseFormat == true)
            {
                Debug.Assert(settings.AcceptableMediaTypes == null, "settings.AcceptableMediaTypes == null");
                Debug.Assert(settings.AcceptableCharsets == null, "settings.AcceptableCharsets == null");

                mediaType = GetDefaultMediaType(supportedMediaTypes, settings.Format, out format);

                // NOTE the default media types don't have any parameters (in particular no 'charset' parameters)
                encoding = mediaType.SelectEncoding();
            }
            else
            {
                // parse the accept header into its parts
                IList <KeyValuePair <MediaType, string> > specifiedTypes = HttpUtils.MediaTypesFromString(settings.AcceptableMediaTypes);

                // Starting in V3 we replace all occurrences of application/json with application/json;odata=minimalmetadata
                // before handing the acceptable media types to the conneg code. This is necessary because for an accept
                // header 'application/json, application/json;odata=verbose' we want to the result to be 'application/json;odata=minimalmetadata'
                // although this is not compliant with the default conneg rules (where application/json;odata=verbose would win).
                if (settings.Version >= ODataVersion.V3)
                {
                    ConvertApplicationJsonInAcceptableMediaTypes(specifiedTypes);
                }

                MediaTypeWithFormat selectedMediaTypeWithFormat;
                string specifiedCharset = null;
                if (specifiedTypes == null || specifiedTypes.Count == 0)
                {
                    selectedMediaTypeWithFormat = supportedMediaTypes[0];
                }
                else
                {
                    // match the specified media types against the supported/default ones and get the format
                    MediaTypeMatchInfo matchInfo = MatchMediaTypes(specifiedTypes.Select(kvp => kvp.Key), supportedMediaTypes.Select(smt => smt.MediaType).ToArray());
                    if (matchInfo == null)
                    {
                        // We're calling the ToArray here since not all platforms support the string.Join which takes IEnumerable.
                        string supportedTypesAsString = String.Join(", ", supportedMediaTypes.Select(mt => mt.MediaType.ToText()).ToArray());
                        throw new ODataContentTypeException(Strings.MediaTypeUtils_DidNotFindMatchingMediaType(supportedTypesAsString, settings.AcceptableMediaTypes));
                    }

                    selectedMediaTypeWithFormat = supportedMediaTypes[matchInfo.TargetTypeIndex];
                    specifiedCharset            = specifiedTypes[matchInfo.SourceTypeIndex].Value;
                }

                format    = selectedMediaTypeWithFormat.Format;
                mediaType = selectedMediaTypeWithFormat.MediaType;

                // If a charset was specified with the accept header, consider it for the encoding
                string acceptableCharsets = settings.AcceptableCharsets;
                if (specifiedCharset != null)
                {
                    acceptableCharsets = acceptableCharsets == null ? specifiedCharset : specifiedCharset + "," + acceptableCharsets;
                }

                encoding = GetEncoding(acceptableCharsets, payloadKind, mediaType, /*useDefaultEncoding*/ true);
            }

            return(format);
        }