コード例 #1
0
        /// <summary>
        /// Converts all occurrences of the 'application/json' media type to 'application/json;odata=minimalmetadata'.
        /// This is necessary because for an accept header 'application/json, application/json;odata=verbose'
        /// we want 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).
        /// </summary>
        /// <param name="specifiedTypes">The parsed acceptable media types.</param>
        private static void ConvertApplicationJsonInAcceptableMediaTypes(IList <KeyValuePair <MediaType, string> > specifiedTypes)
        {
            if (specifiedTypes == null)
            {
                return;
            }

            for (int i = 0; i < specifiedTypes.Count; ++i)
            {
                MediaType mediaType = specifiedTypes[i].Key;
                if (HttpUtils.CompareMediaTypeNames(mediaType.SubTypeName, MimeConstants.MimeJsonSubType) &&
                    HttpUtils.CompareMediaTypeNames(mediaType.TypeName, MimeConstants.MimeApplicationType))
                {
                    if (mediaType.Parameters == null ||
                        !mediaType.Parameters.Any(p => HttpUtils.CompareMediaTypeParameterNames(p.Key, MimeConstants.MimeODataParameterName)))
                    {
                        // application/json detected; convert it to Json Light
                        IList <KeyValuePair <string, string> > existingParams = mediaType.Parameters;
                        int newCount = existingParams == null ? 1 : existingParams.Count + 1;
                        List <KeyValuePair <string, string> > newParams = new List <KeyValuePair <string, string> >(newCount);
                        newParams.Add(new KeyValuePair <string, string>(MimeConstants.MimeODataParameterName, MimeConstants.MimeODataParameterValueMinimalMetadata));
                        if (existingParams != null)
                        {
                            newParams.AddRange(existingParams);
                        }

                        specifiedTypes[i] = new KeyValuePair <MediaType, string>(new MediaType(mediaType.TypeName, mediaType.SubTypeName, newParams), specifiedTypes[i].Value);
                    }
                }
            }
        }
コード例 #2
0
 internal static void CheckMediaTypeForWildCards(MediaType mediaType)
 {
     if (HttpUtils.CompareMediaTypeNames("*", mediaType.TypeName) || HttpUtils.CompareMediaTypeNames("*", mediaType.SubTypeName))
     {
         throw new ODataException(Microsoft.Data.OData.Strings.ODataMessageReader_WildcardInContentType(mediaType.FullTypeName));
     }
 }
コード例 #3
0
 internal Encoding SelectEncoding()
 {
     if (this.parameters != null)
     {
         foreach (string str in from parameter in this.parameters
                  where HttpUtils.CompareMediaTypeParameterNames("charset", parameter.Key)
                  select parameter.Value.Trim() into encodingName
                  where encodingName.Length > 0
                  select encodingName)
         {
             return(EncodingFromName(str));
         }
     }
     if (HttpUtils.CompareMediaTypeNames("text", this.type))
     {
         if (!HttpUtils.CompareMediaTypeNames("xml", this.subType))
         {
             return(MissingEncoding);
         }
         return(null);
     }
     if (HttpUtils.CompareMediaTypeNames("application", this.type) && HttpUtils.CompareMediaTypeNames("json", this.subType))
     {
         return(FallbackEncoding);
     }
     return(null);
 }
コード例 #4
0
 private static IEnumerable <ODataPayloadKind> DetectPayloadKindImplementation(MediaType contentType)
 {
     if (HttpUtils.CompareMediaTypeNames("text", contentType.TypeName) && HttpUtils.CompareMediaTypeNames("text/plain", contentType.SubTypeName))
     {
         return(new ODataPayloadKind[] { ODataPayloadKind.Value });
     }
     return(new ODataPayloadKind[] { ODataPayloadKind.BinaryValue });
 }
コード例 #5
0
 private static IEnumerable <ODataPayloadKind> DetectPayloadKindImplementation(MediaType contentType)
 {
     if (((HttpUtils.CompareMediaTypeNames("multipart", contentType.TypeName) && HttpUtils.CompareMediaTypeNames("mixed", contentType.SubTypeName)) && (contentType.Parameters != null)) && contentType.Parameters.Any <KeyValuePair <string, string> >(kvp => HttpUtils.CompareMediaTypeParameterNames("boundary", kvp.Key)))
     {
         return(new ODataPayloadKind[] { ODataPayloadKind.Batch });
     }
     return(Enumerable.Empty <ODataPayloadKind>());
 }
コード例 #6
0
        /// <summary>
        /// Checks whether two media types with subtypes (but without parameters) are equal.
        /// </summary>
        /// <param name="firstTypeAndSubtype">The first media type and subtype.</param>
        /// <param name="secondTypeAndSubtype">The second media type and subtype.</param>
        /// <returns>true if the <paramref name="firstTypeAndSubtype"/> is equal to <paramref name="secondTypeAndSubtype"/>; otherwise false.</returns>
        internal static bool MediaTypeAndSubtypeAreEqual(string firstTypeAndSubtype, string secondTypeAndSubtype)
        {
            DebugUtils.CheckNoExternalCallers();
            ExceptionUtils.CheckArgumentNotNull(firstTypeAndSubtype, "firstTypeAndSubtype");
            ExceptionUtils.CheckArgumentNotNull(secondTypeAndSubtype, "secondTypeAndSubtype");

            return(HttpUtils.CompareMediaTypeNames(firstTypeAndSubtype, secondTypeAndSubtype));
        }
コード例 #7
0
            private void MatchTypes(MediaType sourceType, MediaType targetType)
            {
                this.MatchingTypeNamePartCount = -1;
                if (sourceType.TypeName == "*")
                {
                    this.MatchingTypeNamePartCount = 0;
                }
                else if (HttpUtils.CompareMediaTypeNames(sourceType.TypeName, targetType.TypeName))
                {
                    if (sourceType.SubTypeName == "*")
                    {
                        this.MatchingTypeNamePartCount = 1;
                    }
                    else if (HttpUtils.CompareMediaTypeNames(sourceType.SubTypeName, targetType.SubTypeName))
                    {
                        this.MatchingTypeNamePartCount = 2;
                    }
                }
                this.QualityValue = 0x3e8;
                this.SourceTypeParameterCountForMatching = 0;
                this.MatchingParameterCount = 0;
                IList <KeyValuePair <string, string> > parameters = sourceType.Parameters;
                IList <KeyValuePair <string, string> > list2      = targetType.Parameters;
                bool flag  = (list2 != null) && (list2.Count > 0);
                bool flag2 = (parameters != null) && (parameters.Count > 0);

                if (flag2)
                {
                    for (int i = 0; i < parameters.Count; i++)
                    {
                        string str2;
                        KeyValuePair <string, string> pair = parameters[i];
                        string key = pair.Key;
                        if (IsQualityValueParameter(key))
                        {
                            KeyValuePair <string, string> pair2 = parameters[i];
                            this.QualityValue = ParseQualityValue(pair2.Value.Trim());
                            break;
                        }
                        this.SourceTypeParameterCountForMatching = i + 1;
                        if (flag && TryFindMediaTypeParameter(list2, key, out str2))
                        {
                            KeyValuePair <string, string> pair3 = parameters[i];
                            if (string.Compare(pair3.Value.Trim(), str2.Trim(), StringComparison.OrdinalIgnoreCase) == 0)
                            {
                                this.MatchingParameterCount++;
                            }
                        }
                    }
                }
                if ((!flag2 || (this.SourceTypeParameterCountForMatching == 0)) || (this.MatchingParameterCount == this.SourceTypeParameterCountForMatching))
                {
                    this.MatchingParameterCount = -1;
                }
            }
コード例 #8
0
        /// <summary>
        /// Checks for wildcard characters in the <see cref="MediaType"/>.
        /// </summary>
        /// <param name="mediaType">The <see cref="MediaType"/> to check.</param>
        internal static void CheckMediaTypeForWildCards(MediaType mediaType)
        {
            DebugUtils.CheckNoExternalCallers();
            Debug.Assert(mediaType != null, "mediaType != null");

            if (HttpUtils.CompareMediaTypeNames(MimeConstants.MimeStar, mediaType.TypeName) ||
                HttpUtils.CompareMediaTypeNames(MimeConstants.MimeStar, mediaType.SubTypeName))
            {
                throw new ODataException(Strings.ODataMessageReader_WildcardInContentType(mediaType.FullTypeName));
            }
        }
コード例 #9
0
ファイル: ODataRawValueFormat.cs プロジェクト: tapika/swupd
        /// <summary>
        /// Detects the payload kind(s) from the message stream.
        /// </summary>
        /// <param name="contentType">The content type of the message.</param>
        /// <returns>An enumerable of zero, one or more payload kinds that were detected from looking at the payload in the message stream.</returns>
        private static IEnumerable <ODataPayloadKind> DetectPayloadKindImplementation(MediaType contentType)
        {
            Debug.Assert(contentType != null, "contentType != null");

            if (HttpUtils.CompareMediaTypeNames(MimeConstants.MimeTextType, contentType.TypeName) &&
                HttpUtils.CompareMediaTypeNames(MimeConstants.MimeTextPlain, contentType.SubTypeName))
            {
                return(new ODataPayloadKind[] { ODataPayloadKind.Value });
            }

            return(new ODataPayloadKind[] { ODataPayloadKind.BinaryValue });
        }
コード例 #10
0
        /// <summary>
        /// Detects the payload kind(s) from the message stream.
        /// </summary>
        /// <param name="contentType">The content type of the message.</param>
        /// <returns>An enumerable of zero, one or more payload kinds that were detected from looking at the payload in the message stream.</returns>
        private static IEnumerable <ODataPayloadKind> DetectPayloadKindImplementation(MediaType contentType)
        {
            // NOTE: for batch payloads we only use the content type header of the message to detect the payload kind.
            //       We assume a valid batch payload if the content type is multipart/mixed and a boundary parameter exists
            // Require 'multipart/mixed' content type with a boundary parameter to be considered batch.
            if (HttpUtils.CompareMediaTypeNames(MimeConstants.MimeMultipartType, contentType.TypeName) &&
                HttpUtils.CompareMediaTypeNames(MimeConstants.MimeMixedSubType, contentType.SubTypeName) &&
                contentType.Parameters != null &&
                contentType.Parameters.Any(kvp => HttpUtils.CompareMediaTypeParameterNames(ODataConstants.HttpMultipartBoundary, kvp.Key)))
            {
                return(new ODataPayloadKind[] { ODataPayloadKind.Batch });
            }

            return(Enumerable.Empty <ODataPayloadKind>());
        }
コード例 #11
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));
            }
        }
コード例 #12
0
        /// <summary>
        /// Removes the application/json media type from the set of specified types since it is not supported in V3 initially
        /// and must not be matched to application/json;odata=verbose.
        /// If no other media types are left, the method will throw.
        /// </summary>
        /// <param name="specifiedTypes">The parsed acceptable media types.</param>
        /// <param name="supportedMediaTypes">The set of supported media types.</param>
        /// <param name="acceptableMediaTypes">The string version of the acceptable media types (for error reporting).</param>
        /// <returns>If nothing was removed the unmodified <paramref name="specifiedTypes"/>; otherwise a cloned list with the unsupported types removed.</returns>
        private static IList <KeyValuePair <MediaType, string> > RemoveApplicationJsonFromAcceptableMediaTypes(
            IList <KeyValuePair <MediaType, string> > specifiedTypes,
            MediaTypeWithFormat[] supportedMediaTypes,
            string acceptableMediaTypes)
        {
            if (specifiedTypes == null)
            {
                return(null);
            }

            List <KeyValuePair <MediaType, string> > filteredTypes = null;

            for (int i = specifiedTypes.Count - 1; i >= 0; --i)
            {
                MediaType mediaType = specifiedTypes[i].Key;
                if (HttpUtils.CompareMediaTypeNames(mediaType.SubTypeName, MimeConstants.MimeJsonSubType) &&
                    HttpUtils.CompareMediaTypeNames(mediaType.TypeName, MimeConstants.MimeApplicationType))
                {
                    if (mediaType.Parameters == null ||
                        !mediaType.Parameters.Where(p => HttpUtils.CompareMediaTypeParameterNames(p.Key, MimeConstants.MimeODataParameterName)).Any())
                    {
                        // application/json detected; remove it from the list
                        if (filteredTypes == null)
                        {
                            filteredTypes = new List <KeyValuePair <MediaType, string> >(specifiedTypes);
                        }

                        filteredTypes.RemoveAt(i);
                    }
                }
            }

            if (filteredTypes == null)
            {
                return(specifiedTypes);
            }

            if (filteredTypes.Count == 0)
            {
                // If we modified the list make sure we still have acceptable media types left; otherwise fail.
                // 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, acceptableMediaTypes));
            }

            return(filteredTypes);
        }
コード例 #13
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));
     }
 }
コード例 #14
0
        /// <summary>
        /// Parse the content type header value to retrieve the boundary and encoding of a changeset.
        /// </summary>
        /// <param name="contentType">The content type to parse.</param>
        private void DetermineChangesetBoundaryAndEncoding(string contentType)
        {
            Debug.Assert(!string.IsNullOrEmpty(contentType), "Should have validated that non-null, non-empty content type header exists.");

            MediaType        mediaType;
            ODataPayloadKind readerPayloadKind;

            MediaTypeUtils.GetFormatFromContentType(
                contentType,
                new ODataPayloadKind[] { ODataPayloadKind.Batch },
                MediaTypeResolver.DefaultMediaTypeResolver,
                out mediaType,
                out this.changesetEncoding,
                out readerPayloadKind,
                out this.changesetBoundary);
            Debug.Assert(readerPayloadKind == ODataPayloadKind.Batch, "Must find batch payload kind.");
            Debug.Assert(this.changesetBoundary != null && this.changesetBoundary.Length > 0, "Boundary string should have been validated by now.");
            Debug.Assert(HttpUtils.CompareMediaTypeNames(MimeConstants.MimeMultipartMixed, mediaType.FullTypeName), "Must be multipart/mixed media type.");
        }
コード例 #15
0
        /// <summary>
        /// Checks for an illegal media type that cannot be caught during content negotiation/resolution
        /// since it would match an unsupported media type.
        /// </summary>
        /// <param name="mediaType">The parsed media type to check.</param>
        /// <returns>true if the media type is illegal (and we should fail); otherwise false.</returns>
        internal bool IsIllegalMediaType(MediaType mediaType)
        {
            DebugUtils.CheckNoExternalCallers();
            Debug.Assert(mediaType != null, "mediaType != null");

            // We fail for JSON-Light for all versions < V3.
            // 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 (this.version < ODataVersion.V3 &&
                HttpUtils.CompareMediaTypeNames(mediaType.SubTypeName, MimeConstants.MimeJsonSubType) &&
                HttpUtils.CompareMediaTypeNames(mediaType.TypeName, MimeConstants.MimeApplicationType) &&
                (mediaType.MediaTypeHasParameterWithValue(MimeConstants.MimeODataParameterName, MimeConstants.MimeODataParameterValueMinimalMetadata) ||
                 mediaType.MediaTypeHasParameterWithValue(MimeConstants.MimeODataParameterName, MimeConstants.MimeODataParameterValueFullMetadata) ||
                 mediaType.MediaTypeHasParameterWithValue(MimeConstants.MimeODataParameterName, MimeConstants.MimeODataParameterValueNoMetadata)))
            {
                return(true);
            }

            return(false);
        }
コード例 #16
0
        /// <summary>
        /// Selects the encoding appropriate for this media type specification
        /// (possibly null).
        /// </summary>
        /// <returns>
        /// The encoding explicitly defined on the media type specification, or
        /// the default encoding for well-known media types.
        /// </returns>
        /// <remarks>
        /// As per http://tools.ietf.org/html/rfc2616#section-3.7, the type,
        /// subtype and parameter name attributes are case-insensitive.
        /// </remarks>
        internal Encoding SelectEncoding()
        {
            DebugUtils.CheckNoExternalCallers();
            if (this.parameters != null)
            {
                foreach (string encodingName in
                         this.parameters.Where(parameter =>
                                               HttpUtils.CompareMediaTypeParameterNames(ODataConstants.Charset, parameter.Key))
                         .Select(parameter => parameter.Value.Trim())
                         .Where(encodingName => encodingName.Length > 0))
                {
                    return(EncodingFromName(encodingName));
                }
            }

            // Select the default encoding for this media type.
            if (HttpUtils.CompareMediaTypeNames(MimeConstants.MimeTextType, this.type))
            {
                // HTTP 3.7.1 Canonicalization and Text Defaults
                // "text" subtypes default to ISO-8859-1
                //
                // Unless the subtype is XML, in which case we should default
                // to us-ascii. Instead we return null, to let the encoding
                // in the <?xml ...?> PI win (http://tools.ietf.org/html/rfc3023#section-3.1)
                return(HttpUtils.CompareMediaTypeNames(MimeConstants.MimeXmlSubType, this.subType) ? null : MissingEncoding);
            }

            if (HttpUtils.CompareMediaTypeNames(MimeConstants.MimeApplicationType, this.type) &&
                HttpUtils.CompareMediaTypeNames(MimeConstants.MimeJsonSubType, this.subType))
            {
                // http://tools.ietf.org/html/rfc4627#section-3
                // The default encoding is UTF-8.
                return(FallbackEncoding);
            }

            return(null);
        }
コード例 #17
0
        private static IList <KeyValuePair <MediaType, string> > RemoveApplicationJsonFromAcceptableMediaTypes(IList <KeyValuePair <MediaType, string> > specifiedTypes, MediaTypeWithFormat[] supportedMediaTypes, string acceptableMediaTypes)
        {
            if (specifiedTypes == null)
            {
                return(null);
            }
            List <KeyValuePair <MediaType, string> > list = null;

            for (int i = specifiedTypes.Count - 1; i >= 0; i--)
            {
                KeyValuePair <MediaType, string> pair = specifiedTypes[i];
                MediaType key = pair.Key;
                if (HttpUtils.CompareMediaTypeNames(key.SubTypeName, "json") && HttpUtils.CompareMediaTypeNames(key.TypeName, "application"))
                {
                    if ((key.Parameters != null) && (from p in key.Parameters
                                                     where HttpUtils.CompareMediaTypeParameterNames(p.Key, "odata")
                                                     select p).Any <KeyValuePair <string, string> >())
                    {
                        continue;
                    }
                    if (list == null)
                    {
                        list = new List <KeyValuePair <MediaType, string> >(specifiedTypes);
                    }
                    list.RemoveAt(i);
                }
            }
            if (list == null)
            {
                return(specifiedTypes);
            }
            if (list.Count == 0)
            {
                throw new ODataContentTypeException(Microsoft.Data.OData.Strings.MediaTypeUtils_DidNotFindMatchingMediaType(string.Join(", ", (from mt in supportedMediaTypes select mt.MediaType.ToText()).ToArray <string>()), acceptableMediaTypes));
            }
            return(list);
        }
コード例 #18
0
            /// <summary>
            /// Matches the source type against the media type.
            /// </summary>
            /// <param name="sourceType">The source <see cref="MediaType"/> to match against the target type.</param>
            /// <param name="targetType">The target <see cref="MediaType"/> to match against the source type.</param>
            private void MatchTypes(MediaType sourceType, MediaType targetType)
            {
                this.MatchingTypeNamePartCount = -1;

                if (sourceType.TypeName == "*")
                {
                    this.MatchingTypeNamePartCount = 0;
                }
                else
                {
                    if (HttpUtils.CompareMediaTypeNames(sourceType.TypeName, targetType.TypeName))
                    {
                        if (sourceType.SubTypeName == "*")
                        {
                            // only type matches
                            this.MatchingTypeNamePartCount = 1;
                        }
                        else if (HttpUtils.CompareMediaTypeNames(sourceType.SubTypeName, targetType.SubTypeName))
                        {
                            // both type and subtype match
                            this.MatchingTypeNamePartCount = 2;
                        }
                    }
                }

                this.QualityValue = DefaultQualityValue;
                this.SourceTypeParameterCountForMatching = 0;
                this.MatchingParameterCount = 0;

                IList <KeyValuePair <string, string> > sourceParameters = sourceType.Parameters;
                IList <KeyValuePair <string, string> > targetParameters = targetType.Parameters;
                bool targetHasParams = targetParameters != null && targetParameters.Count > 0;
                bool sourceHasParams = sourceParameters != null && sourceParameters.Count > 0;

                if (sourceHasParams)
                {
                    for (int i = 0; i < sourceParameters.Count; ++i)
                    {
                        string parameterName = sourceParameters[i].Key;
                        if (IsQualityValueParameter(parameterName))
                        {
                            // once we hit the q-value in the parameters we know that only accept-params will follow
                            // that don't contribute to the matching. Parse the quality value but don't continue processing
                            // parameters.
                            this.QualityValue = ParseQualityValue(sourceParameters[i].Value.Trim());
                            break;
                        }

                        this.SourceTypeParameterCountForMatching = i + 1;

                        if (targetHasParams)
                        {
                            // find the current parameter name in the set of parameters of the candidate and compare the value;
                            // if they match increase the result count
                            // NOTE: according to RFC 2045, Section 2, parameter values are case sensitive per default (while
                            //       type values, subtype values and parameter names are case-insensitive); however, we
                            //       are more relaxed in ODL and allow case insensitive values.
                            string parameterValue;
                            if (TryFindMediaTypeParameter(targetParameters, parameterName, out parameterValue) &&
                                string.Compare(sourceParameters[i].Value.Trim(), parameterValue.Trim(), StringComparison.OrdinalIgnoreCase) == 0)
                            {
                                this.MatchingParameterCount++;
                            }
                        }
                    }
                }

                // if the source does not have parameters or it only has accept extensions
                // (parameters after the q value) or we match all the paramters we
                // have a perfect parameter match.
                if (!sourceHasParams ||
                    this.SourceTypeParameterCountForMatching == 0 ||
                    this.MatchingParameterCount == this.SourceTypeParameterCountForMatching)
                {
                    this.MatchingParameterCount = -1;
                }
            }