Skip to content

Commit 7969b01

Browse files
committed
More JSON extensions
1 parent 1fd1baf commit 7969b01

File tree

11 files changed

+133
-109
lines changed

11 files changed

+133
-109
lines changed

src/RestSharp/Request/RequestContent.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -136,7 +136,7 @@ void AddPostParameters() {
136136
var formContent = new FormUrlEncodedContent(
137137
_request.Parameters
138138
.Where(x => x.Type == ParameterType.GetOrPost)
139-
.Select(x => new KeyValuePair<string, string>(x.Name!, x.Value!.ToString()!))
139+
.Select(x => new KeyValuePair<string, string>(x.Name!, x.Value!.ToString()!))!
140140
);
141141
Content = formContent;
142142
}

src/RestSharp/Request/RestRequest.cs

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -31,16 +31,6 @@ public RestRequest() {
3131
Method = Method.Get;
3232
}
3333

34-
/// <summary>
35-
/// Sets Method property to value of method
36-
/// </summary>
37-
/// <param name="method">Method to use for this request</param>
38-
public RestRequest(Method method) : this() => Method = method;
39-
40-
public RestRequest(string resource, Method method) : this(resource, method, DataFormat.Json) { }
41-
42-
public RestRequest(string resource, DataFormat dataFormat) : this(resource, Method.Get, dataFormat) { }
43-
4434
public RestRequest(string? resource, Method method = Method.Get, DataFormat dataFormat = DataFormat.Json) : this() {
4535
Resource = resource ?? "";
4636
Method = method;

src/RestSharp/RestClientExtensions.Json.cs

Lines changed: 84 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,24 +13,105 @@
1313
// limitations under the License.
1414
//
1515

16+
using System.Net;
17+
1618
namespace RestSharp;
1719

1820
public static partial class RestClientExtensions {
19-
public static Task<TResponse?> PostAsync<TRequest, TResponse>(
21+
/// <summary>
22+
/// Calls the URL specified in the <code>resource</code> parameter, expecting a JSON response back. Deserializes and returns the response.
23+
/// </summary>
24+
/// <param name="client">RestClient instance</param>
25+
/// <param name="resource">Resource URL</param>
26+
/// <param name="cancellationToken">Cancellation token</param>
27+
/// <typeparam name="TResponse">Response object type</typeparam>
28+
/// <returns></returns>
29+
public static Task<TResponse?> GetJsonAsync<TResponse>(this RestClient client, string resource, CancellationToken cancellationToken = default) {
30+
var request = new RestRequest(resource);
31+
return client.GetAsync<TResponse>(request, cancellationToken);
32+
}
33+
34+
/// <summary>
35+
/// Serializes the <code>request</code> object to JSON and makes a POST call to the resource specified in the <code>resource</code> parameter.
36+
/// Expects a JSON response back, deserializes it to <code>TResponse</code> type and returns it.
37+
/// </summary>
38+
/// <param name="client">RestClient instance</param>
39+
/// <param name="resource">Resource URL</param>
40+
/// <param name="request">Request object, must be serializable to JSON</param>
41+
/// <param name="cancellationToken">Cancellation token</param>
42+
/// <typeparam name="TRequest">Request object type</typeparam>
43+
/// <typeparam name="TResponse">Response object type</typeparam>
44+
/// <returns>Deserialized response object</returns>
45+
public static Task<TResponse?> PostJsonAsync<TRequest, TResponse>(
2046
this RestClient client,
47+
string resource,
2148
TRequest request,
2249
CancellationToken cancellationToken = default
2350
) where TRequest : class {
2451
var restRequest = new RestRequest().AddJsonBody(request);
2552
return client.PostAsync<TResponse>(restRequest, cancellationToken);
2653
}
27-
28-
public static Task<TResponse?> PutAsync<TRequest, TResponse>(
54+
55+
/// <summary>
56+
/// Serializes the <code>request</code> object to JSON and makes a POST call to the resource specified in the <code>resource</code> parameter.
57+
/// Expects no response back, just the status code.
58+
/// </summary>
59+
/// <param name="client">RestClient instance</param>
60+
/// <param name="resource">Resource URL</param>
61+
/// <param name="request">Request object, must be serializable to JSON</param>
62+
/// <param name="cancellationToken">Cancellation token</param>
63+
/// <typeparam name="TRequest">Request object type</typeparam>
64+
/// <returns>Response status code</returns>
65+
public static async Task<HttpStatusCode> PostJsonAsync<TRequest>(
2966
this RestClient client,
67+
string resource,
68+
TRequest request,
69+
CancellationToken cancellationToken = default
70+
) where TRequest : class {
71+
var restRequest = new RestRequest().AddJsonBody(request);
72+
var response = await client.PostAsync(restRequest, cancellationToken);
73+
return response.StatusCode;
74+
}
75+
76+
/// <summary>
77+
/// Serializes the <code>request</code> object to JSON and makes a PUT call to the resource specified in the <code>resource</code> parameter.
78+
/// Expects a JSON response back, deserializes it to <code>TResponse</code> type and returns it.
79+
/// </summary>
80+
/// <param name="client">RestClient instance</param>
81+
/// <param name="resource">Resource URL</param>
82+
/// <param name="request">Request object, must be serializable to JSON</param>
83+
/// <param name="cancellationToken">Cancellation token</param>
84+
/// <typeparam name="TRequest">Request object type</typeparam>
85+
/// <typeparam name="TResponse">Response object type</typeparam>
86+
/// <returns>Deserialized response object</returns>
87+
public static Task<TResponse?> PutJsonAsync<TRequest, TResponse>(
88+
this RestClient client,
89+
string resource,
3090
TRequest request,
3191
CancellationToken cancellationToken = default
3292
) where TRequest : class {
3393
var restRequest = new RestRequest().AddJsonBody(request);
3494
return client.PutAsync<TResponse>(restRequest, cancellationToken);
3595
}
96+
97+
/// <summary>
98+
/// Serializes the <code>request</code> object to JSON and makes a PUT call to the resource specified in the <code>resource</code> parameter.
99+
/// Expects no response back, just the status code.
100+
/// </summary>
101+
/// <param name="client">RestClient instance</param>
102+
/// <param name="resource">Resource URL</param>
103+
/// <param name="request">Request object, must be serializable to JSON</param>
104+
/// <param name="cancellationToken">Cancellation token</param>
105+
/// <typeparam name="TRequest">Request object type</typeparam>
106+
/// <returns>Response status code</returns>
107+
public static async Task<HttpStatusCode> PutJsonAsync<TRequest>(
108+
this RestClient client,
109+
string resource,
110+
TRequest request,
111+
CancellationToken cancellationToken = default
112+
) where TRequest : class {
113+
var restRequest = new RestRequest().AddJsonBody(request);
114+
var response = await client.PutAsync(restRequest, cancellationToken);
115+
return response.StatusCode;
116+
}
36117
}

src/RestSharp/RestClientExtensions.cs

Lines changed: 35 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -131,8 +131,11 @@ public static Task<RestResponse<T>> ExecuteAsync<T>(
131131
return response.Data;
132132
}
133133

134-
public static Task GetAsync(this RestClient client, RestRequest request, CancellationToken cancellationToken = default)
135-
=> client.ExecuteAsync(request, Method.Get, cancellationToken);
134+
public static async Task<RestResponse> GetAsync(this RestClient client, RestRequest request, CancellationToken cancellationToken = default) {
135+
var response = await client.ExecuteAsync(request, Method.Get, cancellationToken);
136+
ThrowIfError(response);
137+
return response;
138+
}
136139

137140
/// <summary>
138141
/// Execute the request using POST HTTP method. Exception will be thrown if the request does not succeed.
@@ -149,8 +152,11 @@ public static Task GetAsync(this RestClient client, RestRequest request, Cancell
149152
return response.Data;
150153
}
151154

152-
public static Task<RestResponse> PostAsync(this RestClient client, RestRequest request, CancellationToken cancellationToken = default)
153-
=> client.ExecuteAsync(request, Method.Post, cancellationToken);
155+
public static async Task<RestResponse> PostAsync(this RestClient client, RestRequest request, CancellationToken cancellationToken = default) {
156+
var response = await client.ExecuteAsync(request, Method.Post, cancellationToken);
157+
ThrowIfError(response);
158+
return response;
159+
}
154160

155161
/// <summary>
156162
/// Execute the request using PUT HTTP method. Exception will be thrown if the request does not succeed.
@@ -167,8 +173,11 @@ public static Task<RestResponse> PostAsync(this RestClient client, RestRequest r
167173
return response.Data;
168174
}
169175

170-
public static Task PutAsync(this RestClient client, RestRequest request, CancellationToken cancellationToken = default)
171-
=> client.ExecuteAsync(request, Method.Put, cancellationToken);
176+
public static async Task<RestResponse> PutAsync(this RestClient client, RestRequest request, CancellationToken cancellationToken = default) {
177+
var response = await client.ExecuteAsync(request, Method.Put, cancellationToken);
178+
ThrowIfError(response);
179+
return response;
180+
}
172181

173182
/// <summary>
174183
/// Execute the request using HEAD HTTP method. Exception will be thrown if the request does not succeed.
@@ -185,8 +194,11 @@ public static Task PutAsync(this RestClient client, RestRequest request, Cancell
185194
return response.Data;
186195
}
187196

188-
public static Task HeadAsync(this RestClient client, RestRequest request, CancellationToken cancellationToken = default)
189-
=> client.ExecuteAsync(request, Method.Head, cancellationToken);
197+
public static async Task<RestResponse> HeadAsync(this RestClient client, RestRequest request, CancellationToken cancellationToken = default) {
198+
var response = await client.ExecuteAsync(request, Method.Head, cancellationToken);
199+
ThrowIfError(response);
200+
return response;
201+
}
190202

191203
/// <summary>
192204
/// Execute the request using OPTIONS HTTP method. Exception will be thrown if the request does not succeed.
@@ -203,8 +215,11 @@ public static Task HeadAsync(this RestClient client, RestRequest request, Cancel
203215
return response.Data;
204216
}
205217

206-
public static Task OptionsAsync(this RestClient client, RestRequest request, CancellationToken cancellationToken = default)
207-
=> client.ExecuteAsync(request, Method.Options, cancellationToken);
218+
public static async Task<RestResponse> OptionsAsync(this RestClient client, RestRequest request, CancellationToken cancellationToken = default) {
219+
var response = await client.ExecuteAsync(request, Method.Options, cancellationToken);
220+
ThrowIfError(response);
221+
return response;
222+
}
208223

209224
/// <summary>
210225
/// Execute the request using PATCH HTTP method. Exception will be thrown if the request does not succeed.
@@ -221,8 +236,11 @@ public static Task OptionsAsync(this RestClient client, RestRequest request, Can
221236
return response.Data;
222237
}
223238

224-
public static Task PatchAsync(this RestClient client, RestRequest request, CancellationToken cancellationToken = default)
225-
=> client.ExecuteAsync(request, Method.Patch, cancellationToken);
239+
public static async Task<RestResponse> PatchAsync(this RestClient client, RestRequest request, CancellationToken cancellationToken = default) {
240+
var response = await client.ExecuteAsync(request, Method.Patch, cancellationToken);
241+
ThrowIfError(response);
242+
return response;
243+
}
226244

227245
/// <summary>
228246
/// Execute the request using DELETE HTTP method. Exception will be thrown if the request does not succeed.
@@ -239,8 +257,11 @@ public static Task PatchAsync(this RestClient client, RestRequest request, Cance
239257
return response.Data;
240258
}
241259

242-
public static Task DeleteAsync(this RestClient client, RestRequest request, CancellationToken cancellationToken = default)
243-
=> client.ExecuteAsync(request, Method.Delete, cancellationToken);
260+
public static async Task<RestResponse> DeleteAsync(this RestClient client, RestRequest request, CancellationToken cancellationToken = default) {
261+
var response = await client.ExecuteAsync(request, Method.Delete, cancellationToken);
262+
ThrowIfError(response);
263+
return response;
264+
}
244265

245266
/// <summary>
246267
/// Sets the <see cref="RestClient"/> to only use JSON

src/RestSharp/RestSharp.csproj

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
<Project Sdk="Microsoft.NET.Sdk">
2-
<ItemGroup>
2+
<ItemGroup Condition="$(TargetFramework) != 'net6.0'">
33
<PackageReference Include="System.Text.Json" Version="[5.0,)" />
44
</ItemGroup>
55
<ItemGroup>

test/Directory.Build.props

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,13 +7,15 @@
77
<Nullable>disable</Nullable>
88
</PropertyGroup>
99

10-
<ItemGroup>
10+
<ItemGroup Condition="$(IsTestProject) == 'true'">
1111
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.0.0"/>
12-
<PackageReference Include="xunit" Version="2.4.1"/>
1312
<PackageReference Include="xunit.runner.visualstudio" Version="2.4.3" PrivateAssets="All"/>
13+
<PackageReference Include="coverlet.collector" Version="3.1.0"/>
14+
</ItemGroup>
15+
<ItemGroup>
16+
<PackageReference Include="xunit" Version="2.4.1"/>
1417
<PackageReference Include="AutoFixture" Version="4.17.0"/>
1518
<PackageReference Include="FluentAssertions" Version="5.10.3"/>
16-
<PackageReference Include="coverlet.collector" Version="3.1.0"/>
1719
</ItemGroup>
1820

1921
<ItemGroup>

test/RestSharp.IntegrationTests/OAuth1Tests.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -189,7 +189,7 @@ public void Can_Authenticate_OAuth1_With_Querystring_Parameters() {
189189
};
190190

191191
var client = new RestClient(baseUrl);
192-
var request = new RestRequest(Method.Get);
192+
var request = new RestRequest();
193193
var authenticator = OAuth1Authenticator.ForRequestToken(consumerKey, consumerSecret);
194194
authenticator.ParameterHandling = OAuthParameterHandling.UrlOrPostParameters;
195195
authenticator.Authenticate(client, request);

test/RestSharp.IntegrationTests/StatusCodeTests.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ public StatusCodeTests() {
2424
public async Task ContentType_Additional_Information() {
2525
_server.SetHandler(Handlers.Generic<ResponseHandler>());
2626

27-
var request = new RestRequest(Method.Post) {
27+
var request = new RestRequest("", Method.Post) {
2828
RequestFormat = DataFormat.Json,
2929
Resource = "contenttype_odata"
3030
};

test/RestSharp.InteractiveTests/AuthenticationTests.cs

Lines changed: 2 additions & 71 deletions
Original file line numberDiff line numberDiff line change
@@ -6,77 +6,8 @@ namespace RestSharp.InteractiveTests;
66

77
public class AuthenticationTests {
88
public class TwitterKeys {
9-
public string? ConsumerKey { get; set; }
10-
public string? ConsumerSecret { get; set; }
11-
}
12-
13-
public static async Task Can_Authenticate_With_OAuth(TwitterKeys twitterKeys) {
14-
Console.WriteLine("OAuth test");
15-
16-
var baseUrl = new Uri("https://api.twitter.com");
17-
18-
Console.WriteLine("Getting request token...");
19-
20-
var client = new RestClient(baseUrl) {
21-
Authenticator = OAuth1Authenticator.ForRequestToken(twitterKeys.ConsumerKey, twitterKeys.ConsumerSecret)
22-
};
23-
var request = new RestRequest("oauth/request_token");
24-
var response = await client.ExecuteAsync(request);
25-
26-
Assert.NotNull(response);
27-
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
28-
29-
var qs = HttpUtility.ParseQueryString(response.Content);
30-
var oauthToken = qs["oauth_token"]!;
31-
var oauthTokenSecret = qs["oauth_token_secret"]!;
32-
33-
Assert.NotNull(oauthToken);
34-
Assert.NotNull(oauthTokenSecret);
35-
36-
request = new RestRequest("oauth/authorize?oauth_token=" + oauthToken);
37-
38-
var url = client.BuildUri(request)
39-
.ToString();
40-
41-
Console.WriteLine($"Open this URL in the browser: {url} and complete the authentication.");
42-
Console.Write("Enter the verifier: ");
43-
var verifier = Console.ReadLine();
44-
45-
Console.WriteLine("Getting access token...");
46-
request = new RestRequest("oauth/access_token");
47-
48-
client.Authenticator = OAuth1Authenticator.ForAccessToken(
49-
twitterKeys.ConsumerKey,
50-
twitterKeys.ConsumerSecret,
51-
oauthToken,
52-
oauthTokenSecret,
53-
verifier!
54-
);
55-
response = await client.ExecuteAsync(request);
56-
57-
Console.WriteLine($"Code: {response.StatusCode}, response: {response.Content}");
58-
Assert.NotNull(response);
59-
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
60-
61-
qs = HttpUtility.ParseQueryString(response.Content);
62-
oauthToken = qs["oauth_token"]!;
63-
oauthTokenSecret = qs["oauth_token_secret"]!;
64-
65-
Assert.NotNull(oauthToken);
66-
Assert.NotNull(oauthTokenSecret);
67-
68-
Console.WriteLine("Verifying credentials...");
69-
request = new RestRequest("1.1/account/verify_credentials.json", DataFormat.Json);
70-
71-
client.Authenticator = OAuth1Authenticator.ForProtectedResource(
72-
twitterKeys.ConsumerKey,
73-
twitterKeys.ConsumerSecret,
74-
oauthToken,
75-
oauthTokenSecret
76-
);
77-
response = await client.ExecuteAsync(request);
78-
79-
Console.WriteLine($"Code: {response.StatusCode}, response: {response.Content}");
9+
public string ConsumerKey { get; set; }
10+
public string ConsumerSecret { get; set; }
8011
}
8112

8213
public static async Task Can_Authenticate_With_OAuth_Async_With_Callback(TwitterKeys twitterKeys) {

test/RestSharp.InteractiveTests/Program.cs

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,9 @@
55
ConsumerSecret = Prompt("Consumer secret"),
66
};
77

8-
AuthenticationTests.Can_Authenticate_With_OAuth(keys);
98
await AuthenticationTests.Can_Authenticate_With_OAuth_Async_With_Callback(keys);
109

11-
static string? Prompt(string message) {
12-
Console.Write(message + ": ");
10+
static string Prompt(string message) {
11+
Console.Write($"{message}: ");
1312
return Console.ReadLine();
1413
}

0 commit comments

Comments
 (0)