4
4
using System ;
5
5
using Microsoft . AspNetCore . Mvc . ApiExplorer ;
6
6
using Microsoft . AspNetCore . Mvc . Formatters ;
7
+ using Microsoft . Net . Http . Headers ;
7
8
8
9
namespace Microsoft . AspNetCore . Mvc
9
10
{
@@ -33,6 +34,37 @@ public ProducesResponseTypeAttribute(Type type, int statusCode)
33
34
Type = type ?? throw new ArgumentNullException ( nameof ( type ) ) ;
34
35
StatusCode = statusCode ;
35
36
IsResponseTypeSetByDefault = false ;
37
+ ContentTypes = new ( ) ;
38
+ }
39
+
40
+ /// <summary>
41
+ /// Initializes an instance of <see cref="ProducesResponseTypeAttribute"/>.
42
+ /// </summary>
43
+ /// <param name="type">The <see cref="Type"/> of object that is going to be written in the response.</param>
44
+ /// <param name="statusCode">The HTTP response status code.</param>
45
+ /// <param name="contentType">The content type associated with the response.</param>
46
+ /// <param name="additionalContentTypes">Additional content types supported by the response.</param>
47
+ public ProducesResponseTypeAttribute ( Type type , int statusCode , string ? contentType , params string [ ] additionalContentTypes )
48
+ {
49
+ Type = type ?? throw new ArgumentNullException ( nameof ( type ) ) ;
50
+ StatusCode = statusCode ;
51
+ IsResponseTypeSetByDefault = false ;
52
+
53
+ if ( ! string . IsNullOrEmpty ( contentType ) )
54
+ {
55
+ MediaTypeHeaderValue . Parse ( contentType ) ;
56
+ for ( var i = 0 ; i < additionalContentTypes . Length ; i ++ )
57
+ {
58
+ MediaTypeHeaderValue . Parse ( additionalContentTypes [ i ] ) ;
59
+ }
60
+
61
+ ContentTypes = GetContentTypes ( contentType , additionalContentTypes ) ;
62
+ }
63
+ else
64
+ {
65
+ ContentTypes = new ( ) ;
66
+ }
67
+
36
68
}
37
69
38
70
/// <summary>
@@ -45,6 +77,11 @@ public ProducesResponseTypeAttribute(Type type, int statusCode)
45
77
/// </summary>
46
78
public int StatusCode { get ; set ; }
47
79
80
+ /// <summary>
81
+ /// Gets or sets the content types supported by the response.
82
+ /// </summary>
83
+ public MediaTypeCollection ContentTypes { get ; set ; }
84
+
48
85
/// <summary>
49
86
/// Used to distinguish a `Type` set by default in the constructor versus
50
87
/// one provided by the user.
@@ -58,9 +95,33 @@ public ProducesResponseTypeAttribute(Type type, int statusCode)
58
95
internal bool IsResponseTypeSetByDefault { get ; }
59
96
60
97
/// <inheritdoc />
61
- void IApiResponseMetadataProvider . SetContentTypes ( MediaTypeCollection contentTypes )
98
+ public void SetContentTypes ( MediaTypeCollection contentTypes )
62
99
{
63
- // Users are supposed to use the 'Produces' attribute to set the content types that an action can support.
100
+ contentTypes . Clear ( ) ;
101
+ foreach ( var contentType in ContentTypes )
102
+ {
103
+ contentTypes . Add ( contentType ) ;
104
+ }
105
+ }
106
+
107
+ private MediaTypeCollection GetContentTypes ( string contentType , string [ ] additionalContentTypes )
108
+ {
109
+ List < string > completeContentTypes = new ( additionalContentTypes . Length + 1 ) ;
110
+ completeContentTypes . Add ( contentType ) ;
111
+ completeContentTypes . AddRange ( additionalContentTypes ) ;
112
+ MediaTypeCollection contentTypes = new ( ) ;
113
+ foreach ( var type in completeContentTypes )
114
+ {
115
+ var mediaType = new MediaType ( type ) ;
116
+ if ( mediaType . HasWildcard )
117
+ {
118
+ throw new InvalidOperationException ( "Content types with wild cards are not supported." ) ;
119
+ }
120
+
121
+ contentTypes . Add ( type ) ;
122
+ }
123
+
124
+ return contentTypes ;
64
125
}
65
126
}
66
127
}
0 commit comments