diff --git a/build/dependencies.props b/build/dependencies.props
index 06095e77c8..9d67ef017e 100644
--- a/build/dependencies.props
+++ b/build/dependencies.props
@@ -40,7 +40,7 @@
2.1.0-preview1-27965
2.1.0-preview1-27965
2.1.0-preview1-27965
- 5.2.2
+ 5.2.4-preview1
2.3.1
2.1.0-preview1-27965
2.1.0-preview1-27965
diff --git a/src/Microsoft.AspNetCore.Mvc.WebApiCompatShim/ContentNegotiator/CollectionExtensions.cs b/src/Microsoft.AspNetCore.Mvc.WebApiCompatShim/ContentNegotiator/CollectionExtensions.cs
deleted file mode 100644
index 95cf8c22a1..0000000000
--- a/src/Microsoft.AspNetCore.Mvc.WebApiCompatShim/ContentNegotiator/CollectionExtensions.cs
+++ /dev/null
@@ -1,293 +0,0 @@
-// Copyright (c) .NET Foundation. All rights reserved.
-// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
-
-using System.Collections.ObjectModel;
-using System.Diagnostics;
-using System.Linq;
-
-namespace System.Collections.Generic
-{
- ///
- /// Helper extension methods for fast use of collections.
- ///
- internal static class CollectionExtensions
- {
- ///
- /// Return a new array with the value added to the end. Slow and best suited to long lived arrays with few
- /// writes relative to reads.
- ///
- public static T[] AppendAndReallocate(this T[] array, T value)
- {
- Debug.Assert(array != null);
-
- var originalLength = array.Length;
- var newArray = new T[originalLength + 1];
- array.CopyTo(newArray, 0);
- newArray[originalLength] = value;
- return newArray;
- }
-
- ///
- /// Return the enumerable as an Array, copying if required. Optimized for common case where it is an Array.
- /// Avoid mutating the return value.
- ///
- public static T[] AsArray(this IEnumerable values)
- {
- Debug.Assert(values != null);
-
- var array = values as T[];
- if (array == null)
- {
- array = values.ToArray();
- }
- return array;
- }
-
- ///
- /// Return the enumerable as a Collection of T, copying if required. Optimized for the common case where it is
- /// a Collection of T and avoiding a copy if it implements IList of T. Avoid mutating the return value.
- ///
- public static Collection AsCollection(this IEnumerable enumerable)
- {
- Debug.Assert(enumerable != null);
-
- var collection = enumerable as Collection;
- if (collection != null)
- {
- return collection;
- }
- // Check for IList so that collection can wrap it instead of copying
- var list = enumerable as IList;
- if (list == null)
- {
- list = new List(enumerable);
- }
- return new Collection(list);
- }
-
- ///
- /// Return the enumerable as a IList of T, copying if required. Avoid mutating the return value.
- ///
- public static IList AsIList(this IEnumerable enumerable)
- {
- Debug.Assert(enumerable != null);
-
- var list = enumerable as IList;
- if (list != null)
- {
- return list;
- }
- return new List(enumerable);
- }
-
- ///
- /// Return the enumerable as a List of T, copying if required. Optimized for common case where it is an List of
- /// T or a ListWrapperCollection of T. Avoid mutating the return value.
- ///
- public static List AsList(this IEnumerable enumerable)
- {
- Debug.Assert(enumerable != null);
-
- List list = enumerable as List;
- if (list != null)
- {
- return list;
- }
- ListWrapperCollection listWrapper = enumerable as ListWrapperCollection;
- if (listWrapper != null)
- {
- return listWrapper.ItemsList;
- }
- return new List(enumerable);
- }
-
- ///
- /// Remove values from the list starting at the index start.
- ///
- public static void RemoveFrom(this List list, int start)
- {
- Debug.Assert(list != null);
- Debug.Assert(start >= 0 && start <= list.Count);
-
- list.RemoveRange(start, list.Count - start);
- }
-
- ///
- /// Return the only value from list, the type's default value if empty, or call the errorAction for 2 or more.
- ///
- public static T SingleDefaultOrError(this IList list, Action errorAction, TArg1 errorArg1)
- {
- Debug.Assert(list != null);
- Debug.Assert(errorAction != null);
-
- switch (list.Count)
- {
- case 0:
- return default(T);
-
- case 1:
- var value = list[0];
- return value;
-
- default:
- errorAction(errorArg1);
- return default(T);
- }
- }
-
- ///
- /// Returns a single value in list matching type TMatch if there is only one, null if there are none of type
- /// TMatch or calls the errorAction with errorArg1 if there is more than one.
- ///
- public static TMatch SingleOfTypeDefaultOrError(
- this IList list,
- Action errorAction,
- TArg1 errorArg1) where TMatch : class
- {
- Debug.Assert(list != null);
- Debug.Assert(errorAction != null);
-
- TMatch result = null;
- for (var i = 0; i < list.Count; i++)
- {
- var typedValue = list[i] as TMatch;
- if (typedValue != null)
- {
- if (result == null)
- {
- result = typedValue;
- }
- else
- {
- errorAction(errorArg1);
- return null;
- }
- }
- }
- return result;
- }
-
- ///
- /// Convert an ICollection to an array, removing null values. Fast path for case where there are no null
- /// values.
- ///
- public static T[] ToArrayWithoutNulls(this ICollection collection) where T : class
- {
- Debug.Assert(collection != null);
-
- var result = new T[collection.Count];
- var count = 0;
- foreach (var value in collection)
- {
- if (value != null)
- {
- result[count] = value;
- count++;
- }
- }
- if (count == collection.Count)
- {
- return result;
- }
- else
- {
- var trimmedResult = new T[count];
- Array.Copy(result, trimmedResult, count);
- return trimmedResult;
- }
- }
-
- ///
- /// Convert the array to a Dictionary using the keySelector to extract keys from values and the specified
- /// comparer. Optimized for array input.
- ///
- public static Dictionary ToDictionaryFast(
- this TValue[] array,
- Func keySelector,
- IEqualityComparer comparer)
- {
- Debug.Assert(array != null);
- Debug.Assert(keySelector != null);
-
- var dictionary = new Dictionary(array.Length, comparer);
- for (var i = 0; i < array.Length; i++)
- {
- var value = array[i];
- dictionary.Add(keySelector(value), value);
- }
- return dictionary;
- }
-
- ///
- /// Convert the list to a Dictionary using the keySelector to extract keys from values and the specified
- /// comparer. Optimized for IList of T input with fast path for array.
- ///
- public static Dictionary ToDictionaryFast(
- this IList list,
- Func keySelector,
- IEqualityComparer comparer)
- {
- Debug.Assert(list != null);
- Debug.Assert(keySelector != null);
-
- var array = list as TValue[];
- if (array != null)
- {
- return ToDictionaryFast(array, keySelector, comparer);
- }
- return ToDictionaryFastNoCheck(list, keySelector, comparer);
- }
-
- ///
- /// Convert the enumerable to a Dictionary using the keySelector to extract keys from values and the specified
- /// comparer. Fast paths for array and IList of T.
- ///
- public static Dictionary ToDictionaryFast(
- this IEnumerable enumerable,
- Func keySelector,
- IEqualityComparer comparer)
- {
- Debug.Assert(enumerable != null);
- Debug.Assert(keySelector != null);
-
- var array = enumerable as TValue[];
- if (array != null)
- {
- return ToDictionaryFast(array, keySelector, comparer);
- }
- var list = enumerable as IList;
- if (list != null)
- {
- return ToDictionaryFastNoCheck(list, keySelector, comparer);
- }
- var dictionary = new Dictionary(comparer);
- foreach (var value in enumerable)
- {
- dictionary.Add(keySelector(value), value);
- }
- return dictionary;
- }
-
- ///
- /// Convert the list to a Dictionary using the keySelector to extract keys from values and the specified
- /// comparer. Optimized for IList of T input. No checking for other types.
- ///
- private static Dictionary ToDictionaryFastNoCheck(
- IList list,
- Func keySelector,
- IEqualityComparer comparer)
- {
- Debug.Assert(list != null);
- Debug.Assert(keySelector != null);
-
- var listCount = list.Count;
- var dictionary = new Dictionary(listCount, comparer);
- for (var i = 0; i < listCount; i++)
- {
- var value = list[i];
- dictionary.Add(keySelector(value), value);
- }
- return dictionary;
- }
- }
-}
diff --git a/src/Microsoft.AspNetCore.Mvc.WebApiCompatShim/ContentNegotiator/ContentNegotiationResult.cs b/src/Microsoft.AspNetCore.Mvc.WebApiCompatShim/ContentNegotiator/ContentNegotiationResult.cs
deleted file mode 100644
index 9ba9c47f07..0000000000
--- a/src/Microsoft.AspNetCore.Mvc.WebApiCompatShim/ContentNegotiator/ContentNegotiationResult.cs
+++ /dev/null
@@ -1,50 +0,0 @@
-// Copyright (c) .NET Foundation. All rights reserved.
-// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
-
-using System.Collections.Generic;
-using System.Net.Http.Headers;
-
-namespace System.Net.Http.Formatting
-{
- ///
- /// Represents the result of content negotiation performed using
- ///
- ///
- public class ContentNegotiationResult
- {
- private MediaTypeFormatter _formatter;
-
- ///
- /// Create the content negotiation result object.
- ///
- /// The formatter.
- /// The preferred media type. Can be null.
- public ContentNegotiationResult(MediaTypeFormatter formatter, MediaTypeHeaderValue mediaType)
- {
- if (formatter == null)
- {
- throw new ArgumentNullException(nameof(formatter));
- }
-
- _formatter = formatter;
- MediaType = mediaType;
- }
-
- ///
- /// The formatter chosen for serialization.
- ///
- public MediaTypeFormatter Formatter
- {
- get { return _formatter; }
- set
- {
- _formatter = value;
- }
- }
-
- ///
- /// The media type that is associated with the formatter chosen for serialization. Can be null.
- ///
- public MediaTypeHeaderValue MediaType { get; set; }
- }
-}
diff --git a/src/Microsoft.AspNetCore.Mvc.WebApiCompatShim/ContentNegotiator/DefaultContentNegotiator.cs b/src/Microsoft.AspNetCore.Mvc.WebApiCompatShim/ContentNegotiator/DefaultContentNegotiator.cs
deleted file mode 100644
index b046f2e989..0000000000
--- a/src/Microsoft.AspNetCore.Mvc.WebApiCompatShim/ContentNegotiator/DefaultContentNegotiator.cs
+++ /dev/null
@@ -1,585 +0,0 @@
-// Copyright (c) .NET Foundation. All rights reserved.
-// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
-
-using System.Collections.Generic;
-using System.Collections.ObjectModel;
-using System.Diagnostics;
-using System.Linq;
-using System.Net.Http.Headers;
-using System.Text;
-
-namespace System.Net.Http.Formatting
-{
- ///
- /// Class that selects a for an
- /// or .
- ///
- public class DefaultContentNegotiator : IContentNegotiator
- {
- public DefaultContentNegotiator()
- : this(false)
- {
- }
-
- ///
- /// Initializes a new instance of the with
- /// the given setting for .
- ///
- ///
- /// If ExcludeMatchOnTypeOnly is true then we don't match on type only which means
- /// that we return null if we can't match on anything in the request. This is useful
- /// for generating 406 (Not Acceptable) status codes.
- ///
- public DefaultContentNegotiator(bool excludeMatchOnTypeOnly)
- {
- ExcludeMatchOnTypeOnly = excludeMatchOnTypeOnly;
- }
-
- ///
- /// If ExcludeMatchOnTypeOnly is true then we don't match on type only which means
- /// that we return null if we can't match on anything in the request. This is useful
- /// for generating 406 (Not Acceptable) status codes.
- ///
- public bool ExcludeMatchOnTypeOnly { get; private set; }
-
- ///
- /// Performs content negotiating by selecting the most appropriate out of the
- /// passed in for the given that can serialize an
- /// object of the given .
- ///
- /// The type to be serialized.
- /// The request.
- /// The set of objects from which to choose.
- /// The result of the negotiation containing the most appropriate
- /// instance, or null if there is no appropriate formatter.
- public virtual ContentNegotiationResult Negotiate(
- Type type,
- HttpRequestMessage request,
- IEnumerable formatters)
- {
- if (type == null)
- {
- throw new ArgumentNullException(nameof(type));
- }
-
- if (request == null)
- {
- throw new ArgumentNullException(nameof(request));
- }
-
- if (formatters == null)
- {
- throw new ArgumentNullException(nameof(formatters));
- }
-
- // Go through each formatter to compute how well it matches.
- var matches = ComputeFormatterMatches(type, request, formatters);
-
- // Select best formatter match among the matches
- var bestFormatterMatch = SelectResponseMediaTypeFormatter(matches);
-
- // We found a best formatter
- if (bestFormatterMatch != null)
- {
- var bestMediaType = bestFormatterMatch.MediaType;
-
- // Find the best character encoding for the selected formatter.
- var bestEncodingMatch = SelectResponseCharacterEncoding(request, bestFormatterMatch.Formatter);
- if (bestEncodingMatch != null)
- {
- // Clone media type value since this is not done defensively in this implementation.
- // `MediaTypeHeaderValue` lacks a Clone() method in this runtime. Fortunately, this is the only
- // update to an existing instance we need.
- var clonedMediaType = new MediaTypeHeaderValue(bestMediaType.MediaType);
- foreach (var parameter in bestMediaType.Parameters)
- {
- clonedMediaType.Parameters.Add(new NameValueHeaderValue(parameter.Name, parameter.Value));
- }
-
- bestMediaType = clonedMediaType;
- bestMediaType.CharSet = bestEncodingMatch.WebName;
- }
-
- var bestFormatter =
- bestFormatterMatch.Formatter.GetPerRequestFormatterInstance(type, request, bestMediaType);
- return new ContentNegotiationResult(bestFormatter, bestMediaType);
- }
-
- return null;
- }
-
- ///
- /// Determine how well each formatter matches by associating a
- /// value with the formatter. Then associate the quality of the match based on q-factors and other parameters.
- /// The result of this method is a collection of the matches found categorized and assigned a quality value.
- ///
- /// The type to be serialized.
- /// The request.
- /// The set of objects from which to choose.
- /// A collection containing all the matches.
- protected virtual Collection ComputeFormatterMatches(
- Type type,
- HttpRequestMessage request,
- IEnumerable formatters)
- {
- if (type == null)
- {
- throw new ArgumentNullException(nameof(type));
- }
-
- if (request == null)
- {
- throw new ArgumentNullException(nameof(request));
- }
-
- if (formatters == null)
- {
- throw new ArgumentNullException(nameof(formatters));
- }
-
- IEnumerable sortedAcceptValues = null;
-
- // Go through each formatter to find how well it matches.
- var matches =
- new ListWrapperCollection();
- var writingFormatters = GetWritingFormatters(formatters);
- for (var i = 0; i < writingFormatters.Length; i++)
- {
- var formatter = writingFormatters[i];
-
- // Check first that formatter can write the actual type
- if (!formatter.CanWriteType(type))
- {
- // Formatter can't even write the type so no match at all
- continue;
- }
-
- // Match against the accept header values.
- if (sortedAcceptValues == null)
- {
- // Sort the Accept header values in descending order based on q-factor
- sortedAcceptValues = SortMediaTypeWithQualityHeaderValuesByQFactor(request.Headers.Accept);
- }
-
- var match = MatchAcceptHeader(sortedAcceptValues, formatter);
- if (match != null)
- {
- matches.Add(match);
- continue;
- }
-
- // Match against request's media type if any
- if ((match = MatchRequestMediaType(request, formatter)) != null)
- {
- matches.Add(match);
- continue;
- }
-
- // Check whether we should match on type or stop the matching process.
- // The latter is used to generate 406 (Not Acceptable) status codes.
- var shouldMatchOnType = ShouldMatchOnType(sortedAcceptValues);
-
- // Match against the type of object we are writing out
- if (shouldMatchOnType && (match = MatchType(type, formatter)) != null)
- {
- matches.Add(match);
- continue;
- }
- }
-
- return matches;
- }
-
- ///
- /// Select the best match among the candidate matches found.
- ///
- /// The collection of matches.
- /// The determined to be the best match.
- protected virtual MediaTypeFormatterMatch SelectResponseMediaTypeFormatter(
- ICollection matches)
- {
- if (matches == null)
- {
- throw new ArgumentNullException(nameof(matches));
- }
-
- // Performance-sensitive
-
- var matchList = matches.AsList();
-
- MediaTypeFormatterMatch bestMatchOnType = null;
- MediaTypeFormatterMatch bestMatchOnAcceptHeaderLiteral = null;
- MediaTypeFormatterMatch bestMatchOnAcceptHeaderSubtypeMediaRange = null;
- MediaTypeFormatterMatch bestMatchOnAcceptHeaderAllMediaRange = null;
- MediaTypeFormatterMatch bestMatchOnMediaTypeMapping = null;
- MediaTypeFormatterMatch bestMatchOnRequestMediaType = null;
-
- // Go through each formatter to find the best match in each category.
- for (var i = 0; i < matchList.Count; i++)
- {
- var match = matchList[i];
- switch (match.Ranking)
- {
- case MediaTypeFormatterMatchRanking.MatchOnCanWriteType:
- // First match by type trumps all other type matches
- if (bestMatchOnType == null)
- {
- bestMatchOnType = match;
- }
- break;
-
- case MediaTypeFormatterMatchRanking.MatchOnRequestAcceptHeaderLiteral:
- // Matches on accept headers must choose the highest quality match.
- // A match of 0.0 means we won't use it at all.
- bestMatchOnAcceptHeaderLiteral = UpdateBestMatch(bestMatchOnAcceptHeaderLiteral, match);
- break;
-
- case MediaTypeFormatterMatchRanking.MatchOnRequestAcceptHeaderSubtypeMediaRange:
- // Matches on accept headers must choose the highest quality match.
- // A match of 0.0 means we won't use it at all.
- bestMatchOnAcceptHeaderSubtypeMediaRange =
- UpdateBestMatch(bestMatchOnAcceptHeaderSubtypeMediaRange, match);
- break;
-
- case MediaTypeFormatterMatchRanking.MatchOnRequestAcceptHeaderAllMediaRange:
- // Matches on accept headers must choose the highest quality match.
- // A match of 0.0 means we won't use it at all.
- bestMatchOnAcceptHeaderAllMediaRange =
- UpdateBestMatch(bestMatchOnAcceptHeaderAllMediaRange, match);
- break;
-
- case MediaTypeFormatterMatchRanking.MatchOnRequestMediaType:
- // First match on request content type trumps other request content matches
- if (bestMatchOnRequestMediaType == null)
- {
- bestMatchOnRequestMediaType = match;
- }
- break;
- }
- }
-
- // If we received matches based on both supported media types and from media type mappings,
- // we want to give precedence to the media type mappings, but only if their quality is >= that of the
- // supported media type. We do this because media type mappings are the user's extensibility point and must
- // take precedence over normal supported media types in the case of a tie. The 99% case is where both have
- // quality 1.0.
- if (bestMatchOnMediaTypeMapping != null)
- {
- var mappingOverride = bestMatchOnMediaTypeMapping;
- mappingOverride = UpdateBestMatch(mappingOverride, bestMatchOnAcceptHeaderLiteral);
- mappingOverride = UpdateBestMatch(mappingOverride, bestMatchOnAcceptHeaderSubtypeMediaRange);
- mappingOverride = UpdateBestMatch(mappingOverride, bestMatchOnAcceptHeaderAllMediaRange);
- if (mappingOverride != bestMatchOnMediaTypeMapping)
- {
- bestMatchOnMediaTypeMapping = null;
- }
- }
-
- // now select the formatter and media type
- // A MediaTypeMapping is highest precedence -- it is an extensibility point
- // allowing the user to override normal accept header matching
- MediaTypeFormatterMatch bestMatch = null;
- if (bestMatchOnMediaTypeMapping != null)
- {
- bestMatch = bestMatchOnMediaTypeMapping;
- }
- else if (bestMatchOnAcceptHeaderLiteral != null ||
- bestMatchOnAcceptHeaderSubtypeMediaRange != null ||
- bestMatchOnAcceptHeaderAllMediaRange != null)
- {
- bestMatch = UpdateBestMatch(bestMatch, bestMatchOnAcceptHeaderLiteral);
- bestMatch = UpdateBestMatch(bestMatch, bestMatchOnAcceptHeaderSubtypeMediaRange);
- bestMatch = UpdateBestMatch(bestMatch, bestMatchOnAcceptHeaderAllMediaRange);
- }
- else if (bestMatchOnRequestMediaType != null)
- {
- bestMatch = bestMatchOnRequestMediaType;
- }
- else if (bestMatchOnType != null)
- {
- bestMatch = bestMatchOnType;
- }
-
- return bestMatch;
- }
-
- ///
- /// Determine the best character encoding for writing the response. First we look
- /// for accept-charset headers and if not found then we try to match
- /// any charset encoding in the request (in case of PUT, POST, etc.)
- /// If no encoding is found then we use the default for the formatter.
- ///
- /// The determined to be the best match.
- protected virtual Encoding SelectResponseCharacterEncoding(
- HttpRequestMessage request,
- MediaTypeFormatter formatter)
- {
- if (request == null)
- {
- throw new ArgumentNullException(nameof(request));
- }
-
- if (formatter == null)
- {
- throw new ArgumentNullException(nameof(formatter));
- }
-
- // If there are any SupportedEncodings then we pick an encoding
- var supportedEncodings = formatter.SupportedEncodings.ToList();
- if (supportedEncodings.Count > 0)
- {
- // Sort Accept-Charset header values
- var sortedAcceptCharsetValues =
- SortStringWithQualityHeaderValuesByQFactor(request.Headers.AcceptCharset);
-
- // Check for match based on accept-charset headers
- foreach (StringWithQualityHeaderValue acceptCharset in sortedAcceptCharsetValues)
- {
- for (var i = 0; i < supportedEncodings.Count; i++)
- {
- var encoding = supportedEncodings[i];
- if (encoding != null && acceptCharset.Quality != FormattingUtilities.NoMatch &&
- (acceptCharset.Value.Equals(encoding.WebName, StringComparison.OrdinalIgnoreCase) ||
- acceptCharset.Value.Equals("*", StringComparison.Ordinal)))
- {
- return encoding;
- }
- }
- }
-
- // Check for match based on any request entity body
- return formatter.SelectCharacterEncoding(request.Content != null ? request.Content.Headers : null);
- }
-
- return null;
- }
-
- ///
- /// Match the request accept header field values against the formatter's registered supported media types.
- ///
- /// The sorted accept header values to match.
- /// The formatter to match against.
- ///
- /// A indicating the quality of the match or null is no match.
- ///
- protected virtual MediaTypeFormatterMatch MatchAcceptHeader(
- IEnumerable sortedAcceptValues,
- MediaTypeFormatter formatter)
- {
- if (sortedAcceptValues == null)
- {
- throw new ArgumentNullException(nameof(sortedAcceptValues));
- }
-
- if (formatter == null)
- {
- throw new ArgumentNullException(nameof(formatter));
- }
-
- foreach (MediaTypeWithQualityHeaderValue acceptMediaTypeValue in sortedAcceptValues)
- {
- var supportedMediaTypes = formatter.SupportedMediaTypes.ToList();
- for (var i = 0; i < supportedMediaTypes.Count; i++)
- {
- var supportedMediaType = supportedMediaTypes[i];
- MediaTypeFormatterMatchRanking ranking;
- if (supportedMediaType != null &&
- acceptMediaTypeValue.Quality != FormattingUtilities.NoMatch &&
- supportedMediaType.IsSubsetOf(acceptMediaTypeValue, out ranking))
- {
- return new MediaTypeFormatterMatch(
- formatter,
- supportedMediaType,
- acceptMediaTypeValue.Quality,
- ranking);
- }
- }
- }
-
- return null;
- }
-
- ///
- /// Match any request media type (in case there is a request entity body) against the formatter's registered
- /// media types.
- ///
- /// The request to match.
- /// The formatter to match against.
- ///
- /// A indicating the quality of the match or null is no match.
- ///
- protected virtual MediaTypeFormatterMatch MatchRequestMediaType(
- HttpRequestMessage request,
- MediaTypeFormatter formatter)
- {
- if (request == null)
- {
- throw new ArgumentNullException(nameof(request));
- }
-
- if (formatter == null)
- {
- throw new ArgumentNullException(nameof(formatter));
- }
-
- if (request.Content != null)
- {
- var requestMediaType = request.Content.Headers.ContentType;
- if (requestMediaType != null)
- {
- var supportedMediaTypes = formatter.SupportedMediaTypes.ToList();
- for (var i = 0; i < supportedMediaTypes.Count; i++)
- {
- var supportedMediaType = supportedMediaTypes[i];
- if (supportedMediaType != null && supportedMediaType.IsSubsetOf(requestMediaType))
- {
- return new MediaTypeFormatterMatch(
- formatter,
- supportedMediaType,
- FormattingUtilities.Match,
- MediaTypeFormatterMatchRanking.MatchOnRequestMediaType);
- }
- }
- }
- }
-
- return null;
- }
-
- ///
- /// Determine whether to match on type or not. This is used to determine whether to
- /// generate a 406 response or use the default media type formatter in case there
- /// is no match against anything in the request. If ExcludeMatchOnTypeOnly is true
- /// then we don't match on type unless there are no accept headers.
- ///
- /// The sorted accept header values to match.
- ///
- /// True if not ExcludeMatchOnTypeOnly and accept headers with a q-factor bigger than 0.0 are present.
- ///
- protected virtual bool ShouldMatchOnType(
- IEnumerable sortedAcceptValues)
- {
- if (sortedAcceptValues == null)
- {
- throw new ArgumentNullException(nameof(sortedAcceptValues));
- }
-
- return !(ExcludeMatchOnTypeOnly && sortedAcceptValues.Any());
- }
-
- ///
- /// Pick the first supported media type and indicate we've matched only on type
- ///
- /// The type to be serialized.
- /// The formatter we are matching against.
- ///
- /// A indicating the quality of the match or null is no match.
- ///
- protected virtual MediaTypeFormatterMatch MatchType(
- Type type,
- MediaTypeFormatter formatter)
- {
- if (type == null)
- {
- throw new ArgumentNullException(nameof(type));
- }
-
- if (formatter == null)
- {
- throw new ArgumentNullException(nameof(formatter));
- }
-
- // We already know that we do match on type -- otherwise we wouldn't even be called --
- // so this is just a matter of determining how we match.
- MediaTypeHeaderValue mediaType = null;
- var supportedMediaTypes = formatter.SupportedMediaTypes.ToList();
- if (supportedMediaTypes.Count > 0)
- {
- mediaType = supportedMediaTypes[0];
- }
- return new MediaTypeFormatterMatch(
- formatter,
- mediaType,
- FormattingUtilities.Match,
- MediaTypeFormatterMatchRanking.MatchOnCanWriteType);
- }
-
- ///
- /// Sort Accept header values and related header field values with similar syntax rules
- /// (if more than 1) in descending order based on q-factor.
- ///
- /// The header values to sort.
- /// The sorted header values.
- protected virtual IEnumerable SortMediaTypeWithQualityHeaderValuesByQFactor(
- ICollection headerValues)
- {
- if (headerValues.Count > 1)
- {
- // Use OrderBy() instead of Array.Sort() as it performs fewer comparisons. In this case the comparisons
- // are quite expensive so OrderBy() performs better.
- return headerValues
- .OrderByDescending(m => m, MediaTypeWithQualityHeaderValueComparer.QualityComparer)
- .ToArray();
- }
- else
- {
- return headerValues;
- }
- }
-
- ///
- /// Sort Accept-Charset, Accept-Encoding, Accept-Language and related header field values with similar syntax
- /// rules (if more than 1) in descending order based on q-factor.
- ///
- /// The header values to sort.
- /// The sorted header values.
- protected virtual IEnumerable SortStringWithQualityHeaderValuesByQFactor(
- ICollection headerValues)
- {
- if (headerValues == null)
- {
- throw new ArgumentNullException(nameof(headerValues));
- }
-
- if (headerValues.Count > 1)
- {
- // Use OrderBy() instead of Array.Sort() as it performs fewer comparisons. In this case the comparisons
- // are quite expensive so OrderBy() performs better.
- return headerValues
- .OrderByDescending(m => m, StringWithQualityHeaderValueComparer.QualityComparer)
- .ToArray();
- }
- else
- {
- return headerValues;
- }
- }
-
- ///
- /// Evaluates whether a match is better than the current match and if so returns the replacement; otherwise
- /// returns the current match.
- ///
- protected virtual MediaTypeFormatterMatch UpdateBestMatch(
- MediaTypeFormatterMatch current,
- MediaTypeFormatterMatch potentialReplacement)
- {
- if (potentialReplacement == null)
- {
- return current;
- }
-
- if (current != null)
- {
- return (potentialReplacement.Quality > current.Quality) ? potentialReplacement : current;
- }
-
- return potentialReplacement;
- }
-
- private static MediaTypeFormatter[] GetWritingFormatters(IEnumerable formatters)
- {
- Debug.Assert(formatters != null);
- return formatters.AsArray();
- }
- }
-}
diff --git a/src/Microsoft.AspNetCore.Mvc.WebApiCompatShim/ContentNegotiator/FormDataCollection.cs b/src/Microsoft.AspNetCore.Mvc.WebApiCompatShim/ContentNegotiator/FormDataCollection.cs
deleted file mode 100644
index 2c3ef9bb51..0000000000
--- a/src/Microsoft.AspNetCore.Mvc.WebApiCompatShim/ContentNegotiator/FormDataCollection.cs
+++ /dev/null
@@ -1,40 +0,0 @@
-// Copyright (c) .NET Foundation. All rights reserved.
-// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
-
-using Microsoft.AspNetCore.WebUtilities;
-using System.Collections;
-using System.Collections.Generic;
-
-namespace System.Net.Http.Formatting
-{
- public class FormDataCollection : IEnumerable>
- {
- private readonly IList> _values;
-
- public FormDataCollection(string query)
- {
- var parsedQuery = QueryHelpers.ParseQuery(query);
-
- var values = new List>();
- foreach (var kvp in parsedQuery)
- {
- foreach (var value in kvp.Value)
- {
- values.Add(new KeyValuePair(kvp.Key, value));
- }
- }
-
- _values = values;
- }
-
- public IEnumerator> GetEnumerator()
- {
- return _values.GetEnumerator();
- }
-
- IEnumerator IEnumerable.GetEnumerator()
- {
- return _values.GetEnumerator();
- }
- }
-}
diff --git a/src/Microsoft.AspNetCore.Mvc.WebApiCompatShim/ContentNegotiator/FormattingUtilities.cs b/src/Microsoft.AspNetCore.Mvc.WebApiCompatShim/ContentNegotiator/FormattingUtilities.cs
deleted file mode 100644
index 0a405f8803..0000000000
--- a/src/Microsoft.AspNetCore.Mvc.WebApiCompatShim/ContentNegotiator/FormattingUtilities.cs
+++ /dev/null
@@ -1,236 +0,0 @@
-// Copyright (c) .NET Foundation. All rights reserved.
-// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
-
-using System.Collections.Generic;
-using System.Globalization;
-using System.Linq;
-using System.Net.Http.Formatting;
-using System.Net.Http.Headers;
-using System.Xml;
-using Newtonsoft.Json.Linq;
-
-namespace System.Net.Http
-{
- ///
- /// Provides various internal utility functions
- ///
- internal static class FormattingUtilities
- {
- // Supported date formats for input.
- private static readonly string[] dateFormats = new string[]
- {
- // "r", // RFC 1123, required output format but too strict for input
- "ddd, d MMM yyyy H:m:s 'GMT'", // RFC 1123 (r, except it allows both 1 and 01 for date and time)
- "ddd, d MMM yyyy H:m:s", // RFC 1123, no zone - assume GMT
- "d MMM yyyy H:m:s 'GMT'", // RFC 1123, no day-of-week
- "d MMM yyyy H:m:s", // RFC 1123, no day-of-week, no zone
- "ddd, d MMM yy H:m:s 'GMT'", // RFC 1123, short year
- "ddd, d MMM yy H:m:s", // RFC 1123, short year, no zone
- "d MMM yy H:m:s 'GMT'", // RFC 1123, no day-of-week, short year
- "d MMM yy H:m:s", // RFC 1123, no day-of-week, short year, no zone
-
- "dddd, d'-'MMM'-'yy H:m:s 'GMT'", // RFC 850
- "dddd, d'-'MMM'-'yy H:m:s", // RFC 850 no zone
- "ddd MMM d H:m:s yyyy", // ANSI C's asctime() format
-
- "ddd, d MMM yyyy H:m:s zzz", // RFC 5322
- "ddd, d MMM yyyy H:m:s", // RFC 5322 no zone
- "d MMM yyyy H:m:s zzz", // RFC 5322 no day-of-week
- "d MMM yyyy H:m:s", // RFC 5322 no day-of-week, no zone
- };
-
- // Valid header token characters are within the range 0x20 < c < 0x7F excluding the following characters
- private const string NonTokenChars = "()<>@,;:\\\"/[]?={}";
-
- ///
- /// Quality factor to indicate a perfect match.
- ///
- public const double Match = 1.0;
-
- ///
- /// Quality factor to indicate no match.
- ///
- public const double NoMatch = 0.0;
-
- ///
- /// The default max depth for our formatter is 256
- ///
- public const int DefaultMaxDepth = 256;
-
- ///
- /// The default min depth for our formatter is 1
- ///
- public const int DefaultMinDepth = 1;
-
- ///
- /// HTTP X-Requested-With header field name
- ///
- public const string HttpRequestedWithHeader = "x-requested-with";
-
- ///
- /// HTTP X-Requested-With header field value
- ///
- public const string HttpRequestedWithHeaderValue = "XMLHttpRequest";
-
- ///
- /// HTTP Host header field name
- ///
- public const string HttpHostHeader = "Host";
-
- ///
- /// HTTP Version token
- ///
- public const string HttpVersionToken = "HTTP";
-
- ///
- /// A representing .
- ///
- public static readonly Type HttpRequestMessageType = typeof(HttpRequestMessage);
-
- ///
- /// A representing .
- ///
- public static readonly Type HttpResponseMessageType = typeof(HttpResponseMessage);
-
- ///
- /// A representing .
- ///
- public static readonly Type HttpContentType = typeof(HttpContent);
-
- ///
- /// A representing .
- ///
- public static readonly Type DelegatingEnumerableGenericType = typeof(DelegatingEnumerable<>);
-
- ///
- /// A representing .
- ///
- public static readonly Type EnumerableInterfaceGenericType = typeof(IEnumerable<>);
-
- ///
- /// A representing .
- ///
- public static readonly Type QueryableInterfaceGenericType = typeof(IQueryable<>);
-
- ///
- /// Determines whether is a type.
- ///
- /// The type to test.
- ///
- /// true if is a type; otherwise, false.
- ///
- public static bool IsJTokenType(Type type)
- {
- return typeof(JToken).IsAssignableFrom(type);
- }
-
- ///
- /// Creates an empty instance. The only way is to get it from a dummy
- /// instance.
- ///
- /// The created instance.
- public static HttpContentHeaders CreateEmptyContentHeaders()
- {
- HttpContent tempContent = null;
- HttpContentHeaders contentHeaders;
- try
- {
- tempContent = new StringContent(string.Empty);
- contentHeaders = tempContent.Headers;
- contentHeaders.Clear();
- }
- finally
- {
- // We can dispose the content without touching the headers
- if (tempContent != null)
- {
- tempContent.Dispose();
- }
- }
-
- return contentHeaders;
- }
-
- ///
- /// Create a default reader quotas with a default depth quota of 1K.
- ///
- /// A default with a default depth quota of 1K.
- public static XmlDictionaryReaderQuotas CreateDefaultReaderQuotas()
- {
- // MaxDepth is a DOS mitigation. We don't support MaxDepth in portable libraries because it is strictly
- // client side.
- return new XmlDictionaryReaderQuotas()
- {
- MaxArrayLength = int.MaxValue,
- MaxBytesPerRead = int.MaxValue,
- MaxDepth = DefaultMaxDepth,
- MaxNameTableCharCount = int.MaxValue,
- MaxStringContentLength = int.MaxValue
- };
- }
-
- ///
- /// Remove bounding quotes on a token if present
- ///
- /// Token to unquote.
- /// Unquoted token.
- public static string UnquoteToken(string token)
- {
- if (string.IsNullOrEmpty(token))
- {
- return token;
- }
-
- if (token.StartsWith("\"", StringComparison.Ordinal) &&
- token.EndsWith("\"", StringComparison.Ordinal) &&
- token.Length > 1)
- {
- return token.Substring(1, token.Length - 2);
- }
-
- return token;
- }
-
- public static bool ValidateHeaderToken(string token)
- {
- if (token == null)
- {
- return false;
- }
-
- foreach (char c in token)
- {
- if (c < 0x21 || c > 0x7E || NonTokenChars.IndexOf(c) != -1)
- {
- return false;
- }
- }
-
- return true;
- }
-
- public static string DateToString(DateTimeOffset dateTime)
- {
- // Format according to RFC1123; 'r' uses invariant info (DateTimeFormatInfo.InvariantInfo)
- return dateTime.ToUniversalTime().ToString("r", CultureInfo.InvariantCulture);
- }
-
- public static bool TryParseDate(string input, out DateTimeOffset result)
- {
- return DateTimeOffset.TryParseExact(input, dateFormats, DateTimeFormatInfo.InvariantInfo,
- DateTimeStyles.AllowWhiteSpaces | DateTimeStyles.AssumeUniversal,
- out result);
- }
-
- ///
- /// Parses valid integer strings with no leading signs, whitespace or other
- ///
- /// The value to parse
- /// The result
- /// True if value was valid; false otherwise.
- public static bool TryParseInt32(string value, out int result)
- {
- return int.TryParse(value, NumberStyles.None, NumberFormatInfo.InvariantInfo, out result);
- }
- }
-}
diff --git a/src/Microsoft.AspNetCore.Mvc.WebApiCompatShim/ContentNegotiator/IContentNegotiator.cs b/src/Microsoft.AspNetCore.Mvc.WebApiCompatShim/ContentNegotiator/IContentNegotiator.cs
deleted file mode 100644
index e3ec7d6321..0000000000
--- a/src/Microsoft.AspNetCore.Mvc.WebApiCompatShim/ContentNegotiator/IContentNegotiator.cs
+++ /dev/null
@@ -1,37 +0,0 @@
-// Copyright (c) .NET Foundation. All rights reserved.
-// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
-
-using System.Collections.Generic;
-
-namespace System.Net.Http.Formatting
-{
- ///
- /// Performs content negotiation.
- /// This is the process of selecting a response writer (formatter) in compliance with header values in the request.
- ///
- public interface IContentNegotiator
- {
- ///
- /// Performs content negotiating by selecting the most appropriate out of the
- /// passed in for the given that can serialize an
- /// object of the given .
- ///
- ///
- /// Implementations of this method should call
- /// on the selected formatter and return the result of that method.
- ///
- /// The type to be serialized.
- ///
- /// Request message, which contains the header values used to perform negotiation.
- ///
- /// The set of objects from which to choose.
- ///
- /// The result of the negotiation containing the most appropriate instance,
- /// or null if there is no appropriate formatter.
- ///
- ContentNegotiationResult Negotiate(
- Type type,
- HttpRequestMessage request,
- IEnumerable formatters);
- }
-}
diff --git a/src/Microsoft.AspNetCore.Mvc.WebApiCompatShim/ContentNegotiator/ListWrapperCollection.cs b/src/Microsoft.AspNetCore.Mvc.WebApiCompatShim/ContentNegotiator/ListWrapperCollection.cs
deleted file mode 100644
index 864f865a48..0000000000
--- a/src/Microsoft.AspNetCore.Mvc.WebApiCompatShim/ContentNegotiator/ListWrapperCollection.cs
+++ /dev/null
@@ -1,31 +0,0 @@
-// Copyright (c) .NET Foundation. All rights reserved.
-// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
-
-using System.Collections.Generic;
-
-namespace System.Collections.ObjectModel
-{
- ///
- /// A class that inherits from Collection of T but also exposes its underlying data as List of T for performance.
- ///
- internal sealed class ListWrapperCollection : Collection
- {
- private readonly List _items;
-
- internal ListWrapperCollection()
- : this(new List())
- {
- }
-
- internal ListWrapperCollection(List list)
- : base(list)
- {
- _items = list;
- }
-
- internal List ItemsList
- {
- get { return _items; }
- }
- }
-}
diff --git a/src/Microsoft.AspNetCore.Mvc.WebApiCompatShim/ContentNegotiator/MediaTypeConstants.cs b/src/Microsoft.AspNetCore.Mvc.WebApiCompatShim/ContentNegotiator/MediaTypeConstants.cs
deleted file mode 100644
index bb796c8a07..0000000000
--- a/src/Microsoft.AspNetCore.Mvc.WebApiCompatShim/ContentNegotiator/MediaTypeConstants.cs
+++ /dev/null
@@ -1,109 +0,0 @@
-// Copyright (c) .NET Foundation. All rights reserved.
-// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
-
-using System.Net.Http.Headers;
-
-namespace System.Net.Http.Formatting
-{
- ///
- /// Constants related to media types.
- ///
- internal static class MediaTypeConstants
- {
- private static readonly MediaTypeHeaderValue _defaultApplicationXmlMediaType =
- new MediaTypeHeaderValue("application/xml");
- private static readonly MediaTypeHeaderValue _defaultTextXmlMediaType =
- new MediaTypeHeaderValue("text/xml");
- private static readonly MediaTypeHeaderValue _defaultApplicationJsonMediaType =
- new MediaTypeHeaderValue("application/json");
- private static readonly MediaTypeHeaderValue _defaultTextJsonMediaType =
- new MediaTypeHeaderValue("text/json");
- private static readonly MediaTypeHeaderValue _defaultApplicationOctetStreamMediaType =
- new MediaTypeHeaderValue("application/octet-stream");
- private static readonly MediaTypeHeaderValue _defaultApplicationFormUrlEncodedMediaType =
- new MediaTypeHeaderValue("application/x-www-form-urlencoded");
- private static readonly MediaTypeHeaderValue _defaultApplicationBsonMediaType =
- new MediaTypeHeaderValue("application/bson");
-
- ///
- /// Gets a instance representing application/octet-stream.
- ///
- ///
- /// A new instance representing application/octet-stream.
- ///
- public static MediaTypeHeaderValue ApplicationOctetStreamMediaType
- {
- get { return _defaultApplicationOctetStreamMediaType; }
- }
-
- ///
- /// Gets a instance representing application/xml.
- ///
- ///
- /// A new instance representing application/xml.
- ///
- public static MediaTypeHeaderValue ApplicationXmlMediaType
- {
- get { return _defaultApplicationXmlMediaType; }
- }
-
- ///
- /// Gets a instance representing application/json.
- ///
- ///
- /// A new instance representing application/json.
- ///
- public static MediaTypeHeaderValue ApplicationJsonMediaType
- {
- get { return _defaultApplicationJsonMediaType; }
- }
-
- ///
- /// Gets a instance representing text/xml.
- ///
- ///
- /// A new instance representing text/xml.
- ///
- public static MediaTypeHeaderValue TextXmlMediaType
- {
- get { return _defaultTextXmlMediaType; }
- }
-
- ///
- /// Gets a instance representing text/json.
- ///
- ///
- /// A new instance representing text/json.
- ///
- public static MediaTypeHeaderValue TextJsonMediaType
- {
- get { return _defaultTextJsonMediaType; }
- }
-
- ///
- /// Gets a instance representing application/x-www-form-urlencoded.
- ///
- ///
- /// A new instance representing application/x-www-form-urlencoded.
- ///
- public static MediaTypeHeaderValue ApplicationFormUrlEncodedMediaType
- {
- get { return _defaultApplicationFormUrlEncodedMediaType; }
- }
-
- ///
- /// Gets a instance representing application/bson.
- ///
- ///
- /// A new instance representing application/bson.
- ///
- ///
- /// Not yet a standard. In particular this media type is not currently listed at
- /// https://www.iana.org/assignments/media-types/application.
- ///
- public static MediaTypeHeaderValue ApplicationBsonMediaType
- {
- get { return _defaultApplicationBsonMediaType; }
- }
- }
-}
diff --git a/src/Microsoft.AspNetCore.Mvc.WebApiCompatShim/ContentNegotiator/MediaTypeFormatterMatch.cs b/src/Microsoft.AspNetCore.Mvc.WebApiCompatShim/ContentNegotiator/MediaTypeFormatterMatch.cs
deleted file mode 100644
index a9a7aa0936..0000000000
--- a/src/Microsoft.AspNetCore.Mvc.WebApiCompatShim/ContentNegotiator/MediaTypeFormatterMatch.cs
+++ /dev/null
@@ -1,57 +0,0 @@
-// Copyright (c) .NET Foundation. All rights reserved.
-// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
-
-using System.Net.Http.Headers;
-
-namespace System.Net.Http.Formatting
-{
- ///
- /// This class describes how well a particular matches a request.
- ///
- public class MediaTypeFormatterMatch
- {
- ///
- /// Initializes a new instance of the class.
- ///
- /// The matching formatter.
- ///
- /// The media type. Can be null in which case the media type application/octet-stream is used.
- ///
- ///
- /// The quality of the match. Can be null in which case it is considered a full match with a value of
- /// 1.0.
- ///
- /// The kind of match.
- public MediaTypeFormatterMatch(
- MediaTypeFormatter formatter,
- MediaTypeHeaderValue mediaType,
- double? quality,
- MediaTypeFormatterMatchRanking ranking)
- {
- Formatter = formatter;
- MediaType = mediaType != null ? mediaType : MediaTypeConstants.ApplicationOctetStreamMediaType;
- Quality = quality ?? FormattingUtilities.Match;
- Ranking = ranking;
- }
-
- ///
- /// Gets the media type formatter.
- ///
- public MediaTypeFormatter Formatter { get; private set; }
-
- ///
- /// Gets the matched media type.
- ///
- public MediaTypeHeaderValue MediaType { get; private set; }
-
- ///
- /// Gets the quality of the match
- ///
- public double Quality { get; private set; }
-
- ///
- /// Gets the kind of match that occurred.
- ///
- public MediaTypeFormatterMatchRanking Ranking { get; private set; }
- }
-}
diff --git a/src/Microsoft.AspNetCore.Mvc.WebApiCompatShim/ContentNegotiator/MediaTypeFormatterMatchRanking.cs b/src/Microsoft.AspNetCore.Mvc.WebApiCompatShim/ContentNegotiator/MediaTypeFormatterMatchRanking.cs
deleted file mode 100644
index b79e7c80c8..0000000000
--- a/src/Microsoft.AspNetCore.Mvc.WebApiCompatShim/ContentNegotiator/MediaTypeFormatterMatchRanking.cs
+++ /dev/null
@@ -1,45 +0,0 @@
-// Copyright (c) .NET Foundation. All rights reserved.
-// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
-
-namespace System.Net.Http.Formatting
-{
- ///
- /// Contains information about the degree to which a matches the
- /// explicit or implicit preferences found in an incoming request.
- ///
- public enum MediaTypeFormatterMatchRanking
- {
- ///
- /// No match was found
- ///
- None = 0,
-
- ///
- /// Matched on type meaning that the formatter is able to serialize the type
- ///
- MatchOnCanWriteType,
-
- ///
- /// Matched on explicit literal accept header in ,
- /// e.g. "application/json".
- ///
- MatchOnRequestAcceptHeaderLiteral,
-
- ///
- /// Matched on explicit subtype range accept header in ,
- /// e.g. "application/*".
- ///
- MatchOnRequestAcceptHeaderSubtypeMediaRange,
-
- ///
- /// Matched on explicit all media type range accept header in ,
- /// e.g. "*/*"
- ///
- MatchOnRequestAcceptHeaderAllMediaRange,
-
- ///
- /// Matched on the media type of the of the .
- ///
- MatchOnRequestMediaType,
- }
-}
diff --git a/src/Microsoft.AspNetCore.Mvc.WebApiCompatShim/ContentNegotiator/MediaTypeHeaderValueExtensions.cs b/src/Microsoft.AspNetCore.Mvc.WebApiCompatShim/ContentNegotiator/MediaTypeHeaderValueExtensions.cs
deleted file mode 100644
index ebbec113c8..0000000000
--- a/src/Microsoft.AspNetCore.Mvc.WebApiCompatShim/ContentNegotiator/MediaTypeHeaderValueExtensions.cs
+++ /dev/null
@@ -1,117 +0,0 @@
-// Copyright (c) .NET Foundation. All rights reserved.
-// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
-
-using System.Collections.Generic;
-using System.Diagnostics;
-using System.Net.Http.Headers;
-
-namespace System.Net.Http.Formatting
-{
- ///
- /// Extension methods for .
- ///
- internal static class MediaTypeHeaderValueExtensions
- {
- ///
- /// Determines whether two instances match. The instance
- /// is said to match if and only if
- /// is a strict subset of the values and parameters of
- /// .
- /// That is, if the media type and media type parameters of are all present
- /// and match those of then it is a match even though
- /// may have additional parameters.
- ///
- /// The first media type.
- /// The second media type.
- /// true if this is a subset of ; false otherwise.
- public static bool IsSubsetOf(this MediaTypeHeaderValue mediaType1, MediaTypeHeaderValue mediaType2)
- {
- MediaTypeFormatterMatchRanking mediaType2Range;
- return IsSubsetOf(mediaType1, mediaType2, out mediaType2Range);
- }
-
- ///
- /// Determines whether two instances match. The instance
- /// is said to match if and only if
- /// is a strict subset of the values and parameters of
- /// .
- /// That is, if the media type and media type parameters of are all present
- /// and match those of then it is a match even though
- /// may have additional parameters.
- ///
- /// The first media type.
- /// The second media type.
- ///
- /// Indicates whether is a regular media type, a subtype media range, or a full
- /// media range.
- ///
- /// true if this is a subset of ; false otherwise.
- public static bool IsSubsetOf(
- this MediaTypeHeaderValue mediaType1,
- MediaTypeHeaderValue mediaType2,
- out MediaTypeFormatterMatchRanking mediaType2Range)
- {
- // Performance-sensitive
- Debug.Assert(mediaType1 != null);
-
- if (mediaType2 == null)
- {
- mediaType2Range = MediaTypeFormatterMatchRanking.None;
- return false;
- }
-
- var parsedMediaType1 = new ParsedMediaTypeHeaderValue(mediaType1);
- var parsedMediaType2 = new ParsedMediaTypeHeaderValue(mediaType2);
- mediaType2Range = parsedMediaType2.IsAllMediaRange ? MediaTypeFormatterMatchRanking.MatchOnRequestAcceptHeaderAllMediaRange :
- parsedMediaType2.IsSubtypeMediaRange ? MediaTypeFormatterMatchRanking.MatchOnRequestAcceptHeaderSubtypeMediaRange :
- MediaTypeFormatterMatchRanking.None;
-
- if (!parsedMediaType1.TypesEqual(ref parsedMediaType2))
- {
- if (mediaType2Range != MediaTypeFormatterMatchRanking.MatchOnRequestAcceptHeaderAllMediaRange)
- {
- return false;
- }
- }
- else if (!parsedMediaType1.SubTypesEqual(ref parsedMediaType2))
- {
- if (mediaType2Range != MediaTypeFormatterMatchRanking.MatchOnRequestAcceptHeaderSubtypeMediaRange)
- {
- return false;
- }
- }
- else
- {
- mediaType2Range = MediaTypeFormatterMatchRanking.MatchOnRequestAcceptHeaderLiteral;
- }
-
- // So far we either have a full match or a subset match. Now check that all of
- // mediaType1's parameters are present and equal in mediatype2
- // Optimize for the common case where the parameters inherit from Collection and cache the count which
- // is faster for Collection.
- var parameters1 = mediaType1.Parameters.AsCollection();
- var parameterCount1 = parameters1.Count;
- var parameters2 = mediaType2.Parameters.AsCollection();
- var parameterCount2 = parameters2.Count;
- for (var i = 0; i < parameterCount1; i++)
- {
- var parameter1 = parameters1[i];
- var found = false;
- for (var j = 0; j < parameterCount2; j++)
- {
- var parameter2 = parameters2[j];
- if (parameter1.Equals(parameter2))
- {
- found = true;
- break;
- }
- }
- if (!found)
- {
- return false;
- }
- }
- return true;
- }
- }
-}
diff --git a/src/Microsoft.AspNetCore.Mvc.WebApiCompatShim/ContentNegotiator/MediaTypeWithQualityHeaderComparer.cs b/src/Microsoft.AspNetCore.Mvc.WebApiCompatShim/ContentNegotiator/MediaTypeWithQualityHeaderComparer.cs
deleted file mode 100644
index 02c62a899c..0000000000
--- a/src/Microsoft.AspNetCore.Mvc.WebApiCompatShim/ContentNegotiator/MediaTypeWithQualityHeaderComparer.cs
+++ /dev/null
@@ -1,116 +0,0 @@
-// Copyright (c) .NET Foundation. All rights reserved.
-// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
-
-using System.Collections.Generic;
-using System.Diagnostics;
-using System.Net.Http.Headers;
-
-namespace System.Net.Http.Formatting
-{
- /// Implementation of that can compare accept media type header fields
- /// based on their quality values (a.k.a q-values). See
- /// for a comparer for other content negotiation
- /// header field q-values.
- internal class MediaTypeWithQualityHeaderValueComparer : IComparer
- {
- private static readonly MediaTypeWithQualityHeaderValueComparer _mediaTypeComparer =
- new MediaTypeWithQualityHeaderValueComparer();
-
- private MediaTypeWithQualityHeaderValueComparer()
- {
- }
-
- public static MediaTypeWithQualityHeaderValueComparer QualityComparer
- {
- get { return _mediaTypeComparer; }
- }
-
- ///
- /// Compares two based on their quality value (a.k.a their
- /// "q-value"). Values with identical q-values are considered equal (i.e the result is 0) with the exception
- /// that sub-type wild-cards are considered less than specific media types and full wild-cards are considered
- /// less than sub-type wild-cards. This allows to sort a sequence of
- /// following their q-values in the order of specific media types, subtype wild-cards, and last any full
- /// wild-cards.
- ///
- /// The first to compare.
- /// The second to compare.
- ///
- /// 0 if and are considered equal.
- /// 1 if is considered greater than .
- /// -1 otherwise ( is considered less than ).
- ///
- public int Compare(MediaTypeWithQualityHeaderValue mediaType1, MediaTypeWithQualityHeaderValue mediaType2)
- {
- Debug.Assert(mediaType1 != null, "The 'mediaType1' parameter should not be null.");
- Debug.Assert(mediaType2 != null, "The 'mediaType2' parameter should not be null.");
-
- if (ReferenceEquals(mediaType1, mediaType2))
- {
- return 0;
- }
-
- var returnValue = CompareBasedOnQualityFactor(mediaType1, mediaType2);
- if (returnValue == 0)
- {
- var parsedMediaType1 = new ParsedMediaTypeHeaderValue(mediaType1);
- var parsedMediaType2 = new ParsedMediaTypeHeaderValue(mediaType2);
-
- if (!parsedMediaType1.TypesEqual(ref parsedMediaType2))
- {
- if (parsedMediaType1.IsAllMediaRange)
- {
- return -1;
- }
- else if (parsedMediaType2.IsAllMediaRange)
- {
- return 1;
- }
- else if (parsedMediaType1.IsSubtypeMediaRange && !parsedMediaType2.IsSubtypeMediaRange)
- {
- return -1;
- }
- else if (!parsedMediaType1.IsSubtypeMediaRange && parsedMediaType2.IsSubtypeMediaRange)
- {
- return 1;
- }
- }
- else if (!parsedMediaType1.SubTypesEqual(ref parsedMediaType2))
- {
- if (parsedMediaType1.IsSubtypeMediaRange)
- {
- return -1;
- }
- else if (parsedMediaType2.IsSubtypeMediaRange)
- {
- return 1;
- }
- }
- }
-
- return returnValue;
- }
-
- private static int CompareBasedOnQualityFactor(
- MediaTypeWithQualityHeaderValue mediaType1,
- MediaTypeWithQualityHeaderValue mediaType2)
- {
- Debug.Assert(mediaType1 != null);
- Debug.Assert(mediaType2 != null);
-
- var mediaType1Quality = mediaType1.Quality ?? FormattingUtilities.Match;
- var mediaType2Quality = mediaType2.Quality ?? FormattingUtilities.Match;
- var qualityDifference = mediaType1Quality - mediaType2Quality;
- if (qualityDifference < 0)
- {
- return -1;
- }
- else if (qualityDifference > 0)
- {
- return 1;
- }
-
- return 0;
- }
- }
-}
diff --git a/src/Microsoft.AspNetCore.Mvc.WebApiCompatShim/ContentNegotiator/ParsedMediaTypeHeaderValue.cs b/src/Microsoft.AspNetCore.Mvc.WebApiCompatShim/ContentNegotiator/ParsedMediaTypeHeaderValue.cs
deleted file mode 100644
index 8046dd94d7..0000000000
--- a/src/Microsoft.AspNetCore.Mvc.WebApiCompatShim/ContentNegotiator/ParsedMediaTypeHeaderValue.cs
+++ /dev/null
@@ -1,88 +0,0 @@
-// Copyright (c) .NET Foundation. All rights reserved.
-// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
-
-using System.Diagnostics;
-using System.Net.Http.Headers;
-
-namespace System.Net.Http.Formatting
-{
- // This type is instantiated by frequently called comparison methods so is very performance sensitive
- internal struct ParsedMediaTypeHeaderValue
- {
- private const char MediaRangeAsterisk = '*';
- private const char MediaTypeSubtypeDelimiter = '/';
-
- private readonly string _mediaType;
- private readonly int _delimiterIndex;
- private readonly bool _isAllMediaRange;
- private readonly bool _isSubtypeMediaRange;
-
- public ParsedMediaTypeHeaderValue(MediaTypeHeaderValue mediaTypeHeaderValue)
- {
- Debug.Assert(mediaTypeHeaderValue != null);
- var mediaType = _mediaType = mediaTypeHeaderValue.MediaType;
- _delimiterIndex = mediaType.IndexOf(MediaTypeSubtypeDelimiter);
- Debug.Assert(
- _delimiterIndex > 0,
- "The constructor of the MediaTypeHeaderValue would have failed if there wasn't a type and subtype.");
-
- _isAllMediaRange = false;
- _isSubtypeMediaRange = false;
- var mediaTypeLength = mediaType.Length;
- if (_delimiterIndex == mediaTypeLength - 2)
- {
- if (mediaType[mediaTypeLength - 1] == MediaRangeAsterisk)
- {
- _isSubtypeMediaRange = true;
- if (_delimiterIndex == 1 && mediaType[0] == MediaRangeAsterisk)
- {
- _isAllMediaRange = true;
- }
- }
- }
- }
-
- public bool IsAllMediaRange
- {
- get { return _isAllMediaRange; }
- }
-
- public bool IsSubtypeMediaRange
- {
- get { return _isSubtypeMediaRange; }
- }
-
- public bool TypesEqual(ref ParsedMediaTypeHeaderValue other)
- {
- if (_delimiterIndex != other._delimiterIndex)
- {
- return false;
- }
-
- return string.Compare(
- strA: _mediaType,
- indexA: 0,
- strB: other._mediaType,
- indexB: 0,
- length: _delimiterIndex,
- comparisonType: StringComparison.OrdinalIgnoreCase) == 0;
- }
-
- public bool SubTypesEqual(ref ParsedMediaTypeHeaderValue other)
- {
- var _subTypeLength = _mediaType.Length - _delimiterIndex - 1;
- if (_subTypeLength != other._mediaType.Length - other._delimiterIndex - 1)
- {
- return false;
- }
-
- return string.Compare(
- strA: _mediaType,
- indexA: _delimiterIndex + 1,
- strB: other._mediaType,
- indexB: other._delimiterIndex + 1,
- length: _subTypeLength,
- comparisonType: StringComparison.OrdinalIgnoreCase) == 0;
- }
- }
-}
diff --git a/src/Microsoft.AspNetCore.Mvc.WebApiCompatShim/ContentNegotiator/StringWithQualityHeaderValueComparer.cs b/src/Microsoft.AspNetCore.Mvc.WebApiCompatShim/ContentNegotiator/StringWithQualityHeaderValueComparer.cs
deleted file mode 100644
index 3a2e8222bb..0000000000
--- a/src/Microsoft.AspNetCore.Mvc.WebApiCompatShim/ContentNegotiator/StringWithQualityHeaderValueComparer.cs
+++ /dev/null
@@ -1,75 +0,0 @@
-// Copyright (c) .NET Foundation. All rights reserved.
-// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
-
-using System.Collections.Generic;
-using System.Diagnostics;
-using System.Net.Http.Headers;
-
-namespace System.Net.Http.Formatting
-{
- ///
- /// Implementation of that can compare content negotiation header fields
- /// based on their quality values (a.k.a q-values). This applies to values used in accept-charset,
- /// accept-encoding, accept-language and related header fields with similar syntax rules. See
- /// for a comparer for media type
- /// q-values.
- ///
- internal class StringWithQualityHeaderValueComparer : IComparer
- {
- private static readonly StringWithQualityHeaderValueComparer _qualityComparer =
- new StringWithQualityHeaderValueComparer();
-
- private StringWithQualityHeaderValueComparer()
- {
- }
-
- public static StringWithQualityHeaderValueComparer QualityComparer
- {
- get { return _qualityComparer; }
- }
-
- ///
- /// Compares two based on their quality value (a.k.a their
- /// "q-value"). Values with identical q-values are considered equal (i.e the result is 0) with the exception of
- /// wild-card values (i.e. a value of "*") which are considered less than non-wild-card values. This allows to
- /// sort a sequence of following their q-values ending up with any
- /// wild-cards at the end.
- ///
- /// The first value to compare.
- /// The second value to compare
- /// The result of the comparison.
- public int Compare(
- StringWithQualityHeaderValue stringWithQuality1,
- StringWithQualityHeaderValue stringWithQuality2)
- {
- Debug.Assert(stringWithQuality1 != null);
- Debug.Assert(stringWithQuality2 != null);
-
- var quality1 = stringWithQuality1.Quality ?? FormattingUtilities.Match;
- var quality2 = stringWithQuality2.Quality ?? FormattingUtilities.Match;
- var qualityDifference = quality1 - quality2;
- if (qualityDifference < 0)
- {
- return -1;
- }
- else if (qualityDifference > 0)
- {
- return 1;
- }
-
- if (!string.Equals(stringWithQuality1.Value, stringWithQuality2.Value, StringComparison.OrdinalIgnoreCase))
- {
- if (string.Equals(stringWithQuality1.Value, "*", StringComparison.Ordinal))
- {
- return -1;
- }
- else if (string.Equals(stringWithQuality2.Value, "*", StringComparison.Ordinal))
- {
- return 1;
- }
- }
-
- return 0;
- }
- }
-}
diff --git a/src/Microsoft.AspNetCore.Mvc.WebApiCompatShim/Microsoft.AspNetCore.Mvc.WebApiCompatShim.csproj b/src/Microsoft.AspNetCore.Mvc.WebApiCompatShim/Microsoft.AspNetCore.Mvc.WebApiCompatShim.csproj
index d0b81a0f91..ab1d11a599 100644
--- a/src/Microsoft.AspNetCore.Mvc.WebApiCompatShim/Microsoft.AspNetCore.Mvc.WebApiCompatShim.csproj
+++ b/src/Microsoft.AspNetCore.Mvc.WebApiCompatShim/Microsoft.AspNetCore.Mvc.WebApiCompatShim.csproj
@@ -8,9 +8,6 @@ System.Web.Http.ApiController
$(NoWarn);CS1591
true
aspnetcore;aspnetcoremvc;aspnetwebapi
-
- $(PackageTargetFallback);portable-net451+win8
- true
diff --git a/src/Microsoft.AspNetCore.Mvc.WebApiCompatShim/Properties/AssemblyInfo.cs b/src/Microsoft.AspNetCore.Mvc.WebApiCompatShim/Properties/AssemblyInfo.cs
new file mode 100644
index 0000000000..a97fe6be81
--- /dev/null
+++ b/src/Microsoft.AspNetCore.Mvc.WebApiCompatShim/Properties/AssemblyInfo.cs
@@ -0,0 +1,11 @@
+// Copyright (c) .NET Foundation. All rights reserved.
+// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
+
+using System.Runtime.CompilerServices;
+
+[assembly: TypeForwardedTo(typeof(System.Net.Http.Formatting.ContentNegotiationResult))]
+[assembly: TypeForwardedTo(typeof(System.Net.Http.Formatting.DefaultContentNegotiator))]
+[assembly: TypeForwardedTo(typeof(System.Net.Http.Formatting.FormDataCollection ))]
+[assembly: TypeForwardedTo(typeof(System.Net.Http.Formatting.IContentNegotiator))]
+[assembly: TypeForwardedTo(typeof(System.Net.Http.Formatting.MediaTypeFormatterMatch))]
+[assembly: TypeForwardedTo(typeof(System.Net.Http.Formatting.MediaTypeFormatterMatchRanking))]
diff --git a/src/Microsoft.AspNetCore.Mvc.WebApiCompatShim/breakingchanges.netcore.json b/src/Microsoft.AspNetCore.Mvc.WebApiCompatShim/breakingchanges.netcore.json
new file mode 100644
index 0000000000..1ceaeb35b2
--- /dev/null
+++ b/src/Microsoft.AspNetCore.Mvc.WebApiCompatShim/breakingchanges.netcore.json
@@ -0,0 +1,7 @@
+[
+ {
+ "TypeId": "public enum System.Net.Http.Formatting.MediaTypeFormatterMatchRanking",
+ "MemberId": "MatchOnRequestMediaType = 5",
+ "Kind": "Removal"
+ }
+]
diff --git a/test/Microsoft.AspNetCore.Mvc.FunctionalTests/Microsoft.AspNetCore.Mvc.FunctionalTests.csproj b/test/Microsoft.AspNetCore.Mvc.FunctionalTests/Microsoft.AspNetCore.Mvc.FunctionalTests.csproj
index 6130a01b12..b360623583 100644
--- a/test/Microsoft.AspNetCore.Mvc.FunctionalTests/Microsoft.AspNetCore.Mvc.FunctionalTests.csproj
+++ b/test/Microsoft.AspNetCore.Mvc.FunctionalTests/Microsoft.AspNetCore.Mvc.FunctionalTests.csproj
@@ -3,9 +3,6 @@
$(StandardTestTfms)
-
- $(PackageTargetFallback);portable-net451+win8
- true
$(DefineConstants);GENERATE_BASELINES
diff --git a/test/Microsoft.AspNetCore.Mvc.FunctionalTests/WebApiCompatShimBasicTest.cs b/test/Microsoft.AspNetCore.Mvc.FunctionalTests/WebApiCompatShimBasicTest.cs
index 9834346b79..39c8d8baf8 100644
--- a/test/Microsoft.AspNetCore.Mvc.FunctionalTests/WebApiCompatShimBasicTest.cs
+++ b/test/Microsoft.AspNetCore.Mvc.FunctionalTests/WebApiCompatShimBasicTest.cs
@@ -62,11 +62,7 @@ namespace Microsoft.AspNetCore.Mvc.FunctionalTests
{
typeof(JsonMediaTypeFormatter).FullName,
typeof(XmlMediaTypeFormatter).FullName,
-
-#if NET461
- // We call into WebAPI and ask it to add all of its formatters. On net461 it adds this additional formatter.
typeof(FormUrlEncodedMediaTypeFormatter).FullName
-#endif
};
// Act
diff --git a/test/Microsoft.AspNetCore.Mvc.WebApiCompatShimTest/Microsoft.AspNetCore.Mvc.WebApiCompatShimTest.csproj b/test/Microsoft.AspNetCore.Mvc.WebApiCompatShimTest/Microsoft.AspNetCore.Mvc.WebApiCompatShimTest.csproj
index 6987869a84..b10e11d8e7 100644
--- a/test/Microsoft.AspNetCore.Mvc.WebApiCompatShimTest/Microsoft.AspNetCore.Mvc.WebApiCompatShimTest.csproj
+++ b/test/Microsoft.AspNetCore.Mvc.WebApiCompatShimTest/Microsoft.AspNetCore.Mvc.WebApiCompatShimTest.csproj
@@ -1,12 +1,7 @@
-
- netcoreapp2.1
- $(TargetFrameworks);netcoreapp2.0
-
-
- $(PackageTargetFallback);portable-net451+win8
- true
+
+ $(StandardTestTfms)
true
true
diff --git a/test/WebSites/WebApiCompatShimWebSite/WebApiCompatShimWebSite.csproj b/test/WebSites/WebApiCompatShimWebSite/WebApiCompatShimWebSite.csproj
index 7bf6f180ef..fd4dd53d70 100644
--- a/test/WebSites/WebApiCompatShimWebSite/WebApiCompatShimWebSite.csproj
+++ b/test/WebSites/WebApiCompatShimWebSite/WebApiCompatShimWebSite.csproj
@@ -2,8 +2,6 @@
$(StandardTestWebsiteTfms)
- $(PackageTargetFallback);portable-net451+win8
- true