1
+ #if WEBAPI
2
+ namespace Microsoft . Web . Http . Versioning
3
+ #else
4
+ namespace Microsoft . AspNetCore . Mvc . Versioning
5
+ #endif
6
+ {
7
+ #if WEBAPI
8
+ using Routing ;
9
+ #else
10
+ using Microsoft . AspNetCore . Routing ;
11
+ using Microsoft . Net . Http . Headers ;
12
+ using Routing ;
13
+ #endif
14
+ using System ;
15
+ using System . Collections . Generic ;
16
+ using System . Diagnostics . Contracts ;
17
+ using System . Linq ;
18
+ #if WEBAPI
19
+ using System . Net . Http . Headers ;
20
+ #else
21
+ using MediaTypeWithQualityHeaderValue = Microsoft . Net . Http . Headers . MediaTypeHeaderValue ;
22
+ #endif
23
+
24
+
25
+ /// <summary>
26
+ /// Represents a service API version reader that reads the value from a media type HTTP header in the request.
27
+ /// </summary>
28
+ public partial class MediaTypeApiVersionReader : IApiVersionReader
29
+ {
30
+ string parameterName = "v" ;
31
+
32
+ /// <summary>
33
+ /// Initializes a new instance of the <see cref="MediaTypeApiVersionReader"/> class.
34
+ /// </summary>
35
+ public MediaTypeApiVersionReader ( ) { }
36
+
37
+ /// <summary>
38
+ /// Initializes a new instance of the <see cref="MediaTypeApiVersionReader"/> class.
39
+ /// </summary>
40
+ /// <param name="parameterName">The name of the query string parameter to read the service API version from.</param>
41
+ public MediaTypeApiVersionReader ( string parameterName )
42
+ {
43
+ Arg . NotNullOrEmpty ( parameterName , nameof ( parameterName ) ) ;
44
+ this . parameterName = parameterName ;
45
+ }
46
+
47
+ /// <summary>
48
+ /// Gets or sets the name of the media type parameter to read the service API version from.
49
+ /// </summary>
50
+ /// <value>The name of the media type parameter to read the service API version from.
51
+ /// The default value is "v".</value>
52
+ public string ParameterName
53
+ {
54
+ get
55
+ {
56
+ Contract . Ensures ( ! string . IsNullOrEmpty ( parameterName ) ) ;
57
+ return parameterName ;
58
+ }
59
+ set
60
+ {
61
+ Arg . NotNullOrEmpty ( value , nameof ( value ) ) ;
62
+ parameterName = value ;
63
+ }
64
+ }
65
+
66
+ /// <summary>
67
+ /// Reads the requested API version from the HTTP Accept header.
68
+ /// </summary>
69
+ /// <param name="accept">The <see cref="IEnumerable{T}">sequence</see> of Accept
70
+ /// <see cref="MediaTypeWithQualityHeaderValue">headers</see> to read from.</param>
71
+ /// <returns>The API version read or <c>null</c>.</returns>
72
+ /// <remarks>The default implementation will return the first defined API version ranked by the media type
73
+ /// quality parameter.</remarks>
74
+ protected virtual string ReadAcceptHeader ( IEnumerable < MediaTypeWithQualityHeaderValue > accept )
75
+ {
76
+ Arg . NotNull ( accept , nameof ( accept ) ) ;
77
+
78
+ var comparer = StringComparer . OrdinalIgnoreCase ;
79
+ var contentTypes = from entry in accept
80
+ orderby entry . Quality descending
81
+ group entry by entry . MediaType ;
82
+
83
+ foreach ( var contentType in contentTypes )
84
+ {
85
+ foreach ( var entry in contentType )
86
+ {
87
+ foreach ( var parameter in entry . Parameters )
88
+ {
89
+ if ( comparer . Equals ( parameter . Name , ParameterName ) )
90
+ {
91
+ return parameter . Value ;
92
+ }
93
+ }
94
+ }
95
+ }
96
+
97
+ return null ;
98
+ }
99
+
100
+ /// <summary>
101
+ /// Reads the requested API version from the HTTP Content-Type header.
102
+ /// </summary>
103
+ /// <param name="contentType">The Content-Type <see cref="MediaTypeHeaderValue">header</see> to read from.</param>
104
+ /// <returns>The API version read or <c>null</c>.</returns>
105
+ protected virtual string ReadContentTypeHeader ( MediaTypeHeaderValue contentType )
106
+ {
107
+ Arg . NotNull ( contentType , nameof ( contentType ) ) ;
108
+
109
+ var comparer = StringComparer . OrdinalIgnoreCase ;
110
+
111
+ foreach ( var parameter in contentType . Parameters )
112
+ {
113
+ if ( comparer . Equals ( parameter . Name , ParameterName ) )
114
+ {
115
+ return parameter . Value ;
116
+ }
117
+ }
118
+
119
+ return null ;
120
+ }
121
+ }
122
+ }
0 commit comments