Beispiel #1
0
        /// <summary>
        /// Parses the specified content type header into a media type instance.
        /// </summary>
        /// <param name="contentTypeHeader">The content type header to parse.</param>
        /// <param name="charset">The optional charset specified with the content type.</param>
        /// <returns>The <see cref="ODataMediaType"/> of the parsed <paramref name="contentTypeHeader"/>.</returns>
        private static ODataMediaType ParseContentType(string contentTypeHeader, out string charset)
        {
            Debug.Assert(!String.IsNullOrEmpty(contentTypeHeader), "!string.IsNullOrEmpty(contentTypeHeader)");

            // parse the content type header into its parts, make sure we only allow one content type to be specified.
            IList <KeyValuePair <ODataMediaType, string> > specifiedTypes = HttpUtils.MediaTypesFromString(contentTypeHeader);

            if (specifiedTypes.Count != 1)
            {
                throw new ODataContentTypeException(Strings.MediaTypeUtils_NoOrMoreThanOneContentTypeSpecified(contentTypeHeader));
            }

            ODataMediaType contentType = specifiedTypes[0].Key;

            CheckMediaTypeForWildCards(contentType);
            charset = specifiedTypes[0].Value;
            return(contentType);
        }
Beispiel #2
0
        /// <summary>
        /// Append default values required by OData to specified HTTP header.
        ///
        /// When header name is ODataConstants.ContentTypeHeader, if header value is application/json
        ///     append the following default values for 4.0:
        ///         odata.metadata=minimal
        ///         odata.streaming=true
        ///         IEEE754Compatible=false
        ///     append the following default values for 4.01:
        ///         metadata=minimal
        ///         streaming=true
        ///         IEEE754Compatible=false
        /// </summary>
        /// <param name="headerName">The name of the header to append default values.</param>
        /// <param name="headerValue">The original header value string.</param>
        /// <param name="version">The ODataVersion for which to create the default header value</param>
        /// <returns>The header value string with appended default values.</returns>
        public static string AppendDefaultHeaderValue(string headerName, string headerValue, ODataVersion version)
        {
            if (string.CompareOrdinal(headerName, ODataConstants.ContentTypeHeader) != 0)
            {
                return(headerValue);
            }

            if (headerValue == null)
            {
                return(null);
            }

            var mediaTypeList = HttpUtils.MediaTypesFromString(headerValue);
            var mediaType     = mediaTypeList.Single().Key;
            var encoding      = HttpUtils.GetEncodingFromCharsetName(mediaTypeList.Single().Value);

            if (string.CompareOrdinal(mediaType.FullTypeName, MimeConstants.MimeApplicationJson) != 0)
            {
                return(headerValue);
            }

            var extendedParameters = new List <KeyValuePair <string, string> >();
            var extendedMediaType  = new ODataMediaType(mediaType.Type, mediaType.SubType, extendedParameters);

            var hasMetadata          = false;
            var hasStreaming         = false;
            var hasIeee754Compatible = false;

            if (mediaType.Parameters != null)
            {
                foreach (var parameter in mediaType.Parameters)
                {
                    extendedParameters.Add(parameter);

                    if (HttpUtils.IsMetadataParameter(parameter.Key))
                    {
                        hasMetadata = true;
                    }

                    if (HttpUtils.IsStreamingParameter(parameter.Key))
                    {
                        hasStreaming = true;
                    }

                    if (string.Compare(parameter.Key, MimeConstants.MimeIeee754CompatibleParameterName, StringComparison.OrdinalIgnoreCase) == 0)
                    {
                        hasIeee754Compatible = true;
                    }
                }
            }

            if (!hasMetadata)
            {
                extendedParameters.Add(new KeyValuePair <string, string>(
                                           version < ODataVersion.V401 ? MimeConstants.MimeMetadataParameterName : MimeConstants.MimeShortMetadataParameterName,
                                           MimeConstants.MimeMetadataParameterValueMinimal));
            }

            if (!hasStreaming)
            {
                extendedParameters.Add(new KeyValuePair <string, string>(
                                           version < ODataVersion.V401 ? MimeConstants.MimeStreamingParameterName : MimeConstants.MimeShortStreamingParameterName,
                                           MimeConstants.MimeParameterValueTrue));
            }

            if (!hasIeee754Compatible)
            {
                extendedParameters.Add(new KeyValuePair <string, string>(
                                           MimeConstants.MimeIeee754CompatibleParameterName,
                                           MimeConstants.MimeParameterValueFalse));
            }

            return(extendedMediaType.ToText(encoding));
        }
Beispiel #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,
            ODataMediaTypeResolver mediaTypeResolver,
            out ODataMediaType mediaType,
            out Encoding encoding)
        {
            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 <ODataMediaTypeFormat> supportedMediaTypes = mediaTypeResolver.GetMediaTypeFormats(payloadKind).ToList();

            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 <ODataMediaType, string> > specifiedTypes = HttpUtils.MediaTypesFromString(settings.AcceptableMediaTypes);

                // Starting in V3 we replace all occurrences of application/json with application/json;odata.metadata=minimal
                // before handing the acceptable media types to the conneg code. This is necessary because for an accept
                // header 'application/json, we want to the result to be 'application/json;odata.metadata=minimal'
                ConvertApplicationJsonInAcceptableMediaTypes(specifiedTypes);

                ODataMediaTypeFormat 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);
        }