1+ // MADE Apps licenses this file to you under the MIT license.
2+ // See the LICENSE file in the project root for more information.
3+
4+ namespace MADE . Networking . Http . Responses
5+ {
6+ using System ;
7+ using System . Net ;
8+ using System . Net . Http ;
9+ using System . Net . Http . Headers ;
10+ using System . Threading . Tasks ;
11+ using Newtonsoft . Json ;
12+
13+ /// <summary>
14+ /// Defines a HTTP response message that includes a deserializing option for the response data.
15+ /// </summary>
16+ /// <typeparam name="T">The type of response expected.</typeparam>
17+ public class HttpResponseMessage < T > : IDisposable
18+ {
19+ private HttpResponseMessage response ;
20+ private bool disposed ;
21+
22+ /// <summary>
23+ /// Initializes a new instance of the <see cref="HttpResponseMessage{T}"/> class with the original <see cref="HttpResponseMessage"/>.
24+ /// </summary>
25+ /// <param name="response">The original <see cref="HttpResponseMessage"/>.</param>
26+ public HttpResponseMessage ( HttpResponseMessage response )
27+ {
28+ this . response = response ;
29+ }
30+
31+ /// <summary>
32+ /// Gets the content of the HTTP response message.
33+ /// </summary>
34+ public HttpContent Content => this . response . Content ;
35+
36+ /// <summary>
37+ /// Gets the collection of HTTP response headers.
38+ /// </summary>
39+ public HttpResponseHeaders Headers => this . response . Headers ;
40+
41+ /// <summary>
42+ /// Gets a value indicating whether the HTTP response was successful.
43+ /// </summary>
44+ public bool IsSuccessStatusCode => this . response . IsSuccessStatusCode ;
45+
46+ /// <summary>
47+ /// Gets the reason phrase that typically is sent by servers together with the status code.
48+ /// </summary>
49+ public string ReasonPhrase => this . response . ReasonPhrase ;
50+
51+ /// <summary>
52+ /// Gets the request message which led to this response message.
53+ /// </summary>
54+ public HttpRequestMessage RequestMessage => this . response . RequestMessage ;
55+
56+ /// <summary>
57+ /// Gets the status code of the HTTP response.
58+ /// </summary>
59+ public HttpStatusCode StatusCode => this . response . StatusCode ;
60+
61+ /// <summary>
62+ /// Gets the HTTP message version.
63+ /// </summary>
64+ public Version Version => this . response . Version ;
65+
66+ /// <summary>
67+ /// Gets the deserialized content of the original <see cref="HttpResponseMessage"/> as the specified <typeparamref name="T" /> type.
68+ /// <para>
69+ /// Note, ensure that <see cref="DeserializeAsync"/> has been called first, otherwise this value will be default.
70+ /// </para>
71+ /// </summary>
72+ public T DeserializedContent { get ; private set ; }
73+
74+ /// <summary>
75+ /// Allows conversion of a <see cref="HttpResponseMessage"/> to the <see cref="HttpResponseMessage{T}"/> without direct casting.
76+ /// </summary>
77+ /// <param name="response">
78+ /// The <see cref="HttpResponseMessage"/>.
79+ /// </param>
80+ /// <returns>
81+ /// The <see cref="HttpResponseMessage{T}"/>.
82+ /// </returns>
83+ public static implicit operator HttpResponseMessage < T > ( HttpResponseMessage response )
84+ {
85+ return new HttpResponseMessage < T > ( response ) ;
86+ }
87+
88+ /// <summary>
89+ /// Deserializes the content of the <see cref="HttpResponseMessage"/> into the <see cref="DeserializedContent"/> value.
90+ /// </summary>
91+ /// <returns>A <see cref="Task"/> representing the result of the asynchronous operation.</returns>
92+ public async Task < T > DeserializeAsync ( )
93+ {
94+ this . DeserializedContent = JsonConvert . DeserializeObject < T > ( await this . Content . ReadAsStringAsync ( ) ) ;
95+ return this . DeserializedContent ;
96+ }
97+
98+ /// <summary>
99+ /// Throws an exception if the <see cref="IsSuccessStatusCode"/> property for the HTTP response is false.
100+ /// </summary>
101+ /// <returns>The HTTP response message if the call is successful.</returns>
102+ public HttpResponseMessage < T > EnsureSuccessStatusCode ( )
103+ {
104+ this . response . EnsureSuccessStatusCode ( ) ;
105+ return this ;
106+ }
107+
108+ /// <summary>
109+ /// Releases the unmanaged resources and disposes of unmanaged resources used by the <see cref="HttpResponseMessage{T}"/>.
110+ /// </summary>
111+ public void Dispose ( )
112+ {
113+ this . Dispose ( disposing : true ) ;
114+ GC . SuppressFinalize ( this ) ;
115+ }
116+
117+ /// <summary>
118+ /// Releases the unmanaged resources used by the <see cref="HttpResponseMessage{T}"/> and optionally disposes of the managed resources.
119+ /// </summary>
120+ /// <param name="disposing">A value indicating whether to release both managed and unmanaged resources.</param>
121+ protected virtual void Dispose ( bool disposing )
122+ {
123+ if ( ! this . disposed )
124+ {
125+ if ( disposing )
126+ {
127+ this . response . Dispose ( ) ;
128+ }
129+
130+ this . response = null ;
131+ this . DeserializedContent = default ;
132+ this . disposed = true ;
133+ }
134+ }
135+ }
136+ }
0 commit comments