Skip to content

Commit 5187c41

Browse files
committed
Docs improvements
1 parent c486e78 commit 5187c41

File tree

8 files changed

+290
-190
lines changed

8 files changed

+290
-190
lines changed

docs/.vuepress/config.js

Lines changed: 5 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ module.exports = {
55
themeConfig: {
66
logo: "/restsharp.png",
77
navbar: [
8-
{text: "Migration", link: "/v107/"},
8+
{text: "Migration to v107", link: "/v107/"},
99
{text: "Documentation", link: "/intro.html"},
1010
{text: "Get help", link: "/support/"},
1111
{text: "NuGet", link: "https://nuget.org/packages/RestSharp"}
@@ -19,14 +19,16 @@ module.exports = {
1919
children: [
2020
"intro.md",
2121
"usage.md",
22-
"authenticators.md"
22+
"serialization.md",
23+
"authenticators.md",
24+
"error-handling.md"
2325
]
2426
}
2527
],
2628
"/v107/": [
2729
{
2830
text: "",
29-
header: "RestSharp vNext",
31+
header: "Migration to v107",
3032
children: [
3133
"/v107/README.md"
3234
]
@@ -42,37 +44,6 @@ module.exports = {
4244
}
4345
]
4446
},
45-
// [
46-
// {
47-
// title: "Getting Started",
48-
// path: "/getting-started/",
49-
// collapsable: false,
50-
// children: [
51-
// "/getting-started/",
52-
// "/getting-started/getting-started"
53-
// ]
54-
// },
55-
// {
56-
// title: "Using RestSharp",
57-
// path: "/usage/",
58-
// collapsable: false,
59-
// children: [
60-
// "/usage/serialization",
61-
// "/usage/files",
62-
// "/usage/authenticators",
63-
// "/usage/parameters",
64-
// "/usage/exceptions"
65-
// ]
66-
// },
67-
// {
68-
// title: "Got stuck?",
69-
// path: "/get-help/",
70-
// collapsable: false,
71-
// children: [
72-
// "/get-help/faq"
73-
// ]
74-
// }
75-
// ],
7647
searchPlaceholder: "Search...",
7748
lastUpdated: "Last Updated",
7849
repo: "restsharp/RestSharp",

docs/README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ features:
1414
- title: Extensive configuration
1515
details: Almost every aspect of an HTTP call can be customized
1616
- title: Authentication
17-
details: Basic, OAuth 1, OAuth 2, and JWT are supported. Not enough? Write your own!
17+
details: Basic, OAuth1, OAuth2, and JWT are supported. Not enough? Write your own!
1818
- title: Forms, request body, and files
1919
details: Send objects as the request body in JSON or XML, or as a form. Upload and download files as bytes or as streams.
2020
- title: Parameters

docs/authenticators.md

Lines changed: 34 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ NTLM and parameter-based systems.
55

66
## Basic Authentication
77

8-
The `HttpBasicAuthenticator` allows you pass a username and password as a basica auth Authorization header.
8+
The `HttpBasicAuthenticator` allows you pass a username and password as a basic `Authorization` header using a base64 encoded string.
99

1010
```csharp
1111
var client = new RestClient("http://example.com");
@@ -31,27 +31,48 @@ This method retrieves an access token when provided `consumerKey`, `consumerSecr
3131

3232
```csharp
3333
client.Authenticator = OAuth1Authenticator.ForAccessToken(
34-
consumerKey, consumerSecret, oauthToken,
35-
oauthTokenSecret
36-
);
34+
consumerKey, consumerSecret, oauthToken, oauthTokenSecret
35+
);
3736
```
3837

3938
This method also includes an optional parameter to specify the `OAuthSignatureMethod`.
4039
```csharp
41-
client.Authenticator = OAuth1Authenticator.ForAccessToken(consumerKey,
42-
consumerSecret,
43-
oauthToken,
44-
oauthTokenSecret,
45-
OAuthSignatureMethod.PlainText);
40+
client.Authenticator = OAuth1Authenticator.ForAccessToken(
41+
consumerKey, consumerSecret, oauthToken, oauthTokenSecret,
42+
OAuthSignatureMethod.PlainText
43+
);
4644
```
4745

4846
### 0-legged OAuth
4947

5048
The same access token authenticator can be used in 0-legged OAuth scenarios by providing `null` for the `consumerSecret`.
49+
50+
```csharp
51+
client.Authenticator = OAuth1Authenticator.ForAccessToken(
52+
consumerKey, null, oauthToken, oauthTokenSecret
53+
);
54+
```
55+
56+
## OAuth2
57+
58+
RestSharp has two very simple authenticators to send the access token as part of the request.
59+
60+
`OAuth2UriQueryParameterAuthenticator` accepts the access token as the only constructor argument, and it will send the provided token as a query parameter `oauth_token`.
61+
62+
`OAuth2AuthorizationRequestHeaderAuthenticator` has two constructors. One only accepts a single argument, which is the access token. The other constructor also allows you to specify the token type. The authenticator will then add an `Authorization` header using the specified token type or `OAuth` as the default token type, and the token itself.
63+
64+
For example:
65+
5166
```csharp
52-
client.Authenticator = OAuth1Authenticator.ForAccessToken(consumerKey, null, oauthToken, oauthTokenSecret);
67+
client.Authenticator = new OAuth2AuthorizationRequestHeaderAuthenticator(
68+
"Bearer", token
69+
);
5370
```
5471

72+
The code above will tell RestSharp to send the bearer token with each request as a header. Essentially, the code above does the same as the sample for `JwtAuthenticator` below.
73+
74+
As those authenticators don't do much to get the token itself, you might be interested in looking at our [sample OAuth2 authenticator](usage.md#authenticator), which requests the token on its own.
75+
5576
## JWT
5677

5778
The JWT authentication can be supported by using `JwtAuthenticator`. It is a very simple class that can be constructed like this:
@@ -74,7 +95,6 @@ var client = new RestClient();
7495
client.Authenticator = new SuperAuthenticator(); // implements IAuthenticator
7596
```
7697

77-
The `Authenticate` method is the very first thing called upon calling
78-
`RestClient.Execute` or `RestClient.Execute<T>`.
79-
The `Authenticate` method is passed the `RestRequest` currently being executed giving
80-
you access to every part of the request data (headers, parameters, etc.)
98+
The `Authenticate` method is the very first thing called upon calling `RestClient.Execute` or `RestClient.Execute<T>`. The `Authenticate` method is passed the `RestRequest` currently being executed giving you access to every part of the request data (headers, parameters, etc.)
99+
100+
You can find an example of a custom authenticator that fetches and uses an OAuth2 bearer token [here](usage.md#authenticator).

docs/error-handling.md

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
# Error handling
2+
3+
If there is a network transport error (network is down, failed DNS lookup, etc), or any kind of server error (except 404), `RestResponse.ResponseStatus` will be set to `ResponseStatus.Error`, otherwise it will be `ResponseStatus.Completed`.
4+
5+
If an API returns a 404, `ResponseStatus` will still be `Completed`. If you need access to the HTTP status code returned you will find it at `RestResponse.StatusCode`.
6+
The `Status` property is an indicator of completion independent of the API error handling.
7+
8+
Normally, RestSharp doesn't throw an exception if the request fails.
9+
10+
However, it is possible to configure RestSharp to throw in different situations, when it normally doesn't throw
11+
in favour of giving you the error as a property.
12+
13+
| Property | Behavior |
14+
|-------------------------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
15+
| `FailOnDeserializationError` | Changes the default behavior when failed deserialization results in a successful response with an empty `Data` property of the response. Setting this property to `true` will tell RestSharp to consider failed deserialization as an error and set the `ResponseStatus` to `Error` accordingly. |
16+
| `ThrowOnDeserializationError` | Changes the default behavior when failed deserialization results in empty `Data` property of the response. Setting this property to `true` will tell RestSharp to throw when deserialization fails. |
17+
| `ThrowOnAnyError` | Setting this property to `true` changes the default behavior and forces RestSharp to throw if any errors occurs when making a request or during deserialization. |
18+
19+
Those properties are available for the `RestClient` instance and will be used for all request made with that instance.
20+
21+
::: warning
22+
Please be aware that deserialization failures will only work if the serializer throws an exception when deserializing the response.
23+
Many serializers don't throw by default, and just return a `null` result. RestSharp is unable to figure out why `null` is returned, so it won't fail in this case.
24+
Check the serializer documentation to find out if it can be configured to throw on deserialization error.
25+
:::
26+
27+
There are also slight differences on how different overloads handle exceptions.
28+
29+
Asynchronous generic methods `GetAsync<T>`, `PostAsync<T>` and so on, which aren't a part of `RestClient` interface (those methods are extension methods) return `Task<T>`. It means that there's no `RestResponse` to set the response status to error. We decided to throw an exception when such a request fails. It is a trade-off between the API consistency and usability of the library. Usually, you only need the content of `RestResponse` instance to diagnose issues and most of the time the exception would tell you what's wrong.
30+
31+
Below you can find how different extensions deal with errors. Note that functions, which don't throw by default, will throw exceptions when `ThrowOnAnyError` is set to `true`.
32+
33+
| Function | Throws on errors |
34+
|:----------------------|:-----------------|
35+
| `ExecuteAsync` | No |
36+
| `ExecuteGetAsync` | No |
37+
| `ExecuteGetAsync<T>` | No |
38+
| `ExecutePostAsync` | No |
39+
| `ExecutePutAsync` | No |
40+
| `ExecuteGetAsync<T>` | No |
41+
| `ExecutePostAsync<T>` | No |
42+
| `ExecutePutAsync<T>` | No |
43+
| `GetAsync` | Yes |
44+
| `GetAsync<T>` | Yes |
45+
| `PostAsync` | Yes |
46+
| `PostAsync<T>` | Yes |
47+
| `PatchAsync` | Yes |
48+
| `PatchAsync<T>` | Yes |
49+
| `DeleteAsync` | Yes |
50+
| `DeleteAsync<T>` | Yes |
51+
| `OptionsAsync` | Yes |
52+
| `OptionsAsync<T>` | Yes |
53+
| `HeadAsync` | Yes |
54+
| `HeadAsync<T>` | Yes |
55+
56+
In addition, all the functions for JSON requests, like `GetJsonAsync` and `PostJsonAsyn` throw an exception if the HTTP call fails.

docs/intro.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ throw an exception.
5959

6060
All `ExecuteAsync` overloads, however, behave in the same way as `Execute` and return the `IRestResponse` or `IRestResponse<T>`.
6161

62-
Read [here](usage.md#error-handling) about how RestSharp handles exceptions.
62+
Read [here](error-handling.md) about how RestSharp handles exceptions.
6363

6464
### Content type
6565

@@ -76,6 +76,8 @@ var request = new RestRequest("address/update").AddJsonBody(updatedAddress);
7676
var response = await client.PostAsync<AddressUpdateResponse>(request);
7777
```
7878

79+
Read more about serialization and deserialization [here](serialization.md).
80+
7981
### Response
8082

8183
When you use `ExecuteAsync`, you get an instance of `RestResponse` back that has the `Content` property, which contains the response as string. You can find other useful properties there, like `StatusCode`, `ContentType` and so on. If the request wasn't successful, you'd get a response back with `IsSuccessful` property set to `false` and the error explained in the `ErrorException` and `ErrorMessage` properties.

docs/serialization.md

Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
# Serialization
2+
3+
RestSharp has JSON and XML serializers built in.
4+
5+
:::tip
6+
The default behavior of RestSharp is to swallow deserialization errors and return `null` in the `Data`
7+
property of the response. Read more about it in the [Error Handling](error-handling.md).
8+
:::
9+
10+
## JSON
11+
12+
The default JSON serializer uses `System.Text.Json`, which is a part of .NET since .NET 6. For earlier versions, it is added as a dependency. There are also a few serializers provided as additional packages.
13+
14+
## XML
15+
16+
The default XML serializer is `DotNetXmlSerializer`, which uses `System.Xml.Serialization` library from .NET.
17+
18+
In previous versions of RestSharp, the default XML serializer was a custom RestSharp XML serializer. To make the code library size smaller, that serializer is now available as a separate package [`RestSharp.Serializers.Xml`](https://www.nuget.org/packages/RestSharp.Serializers.Xml).
19+
You can add it back if necessary by installing the package and adding it to the client:
20+
21+
```csharp
22+
client.UseXmlSerializer();
23+
```
24+
25+
As before, you can supply three optional arguments for a custom namespace, custom root element, and if you want to use `SerializeAs` and `DeserializeAs` attributed.
26+
27+
## NewtonsoftJson (aka Json.Net)
28+
29+
The `NewtonsoftJson` package is the most popular JSON serializer for .NET. It handles all possible scenarios and is very configurable. Such a flexibility comes with the cost of performance. If you need speed, keep the default JSON serializer.
30+
31+
RestSharp support Json.Net serializer via a separate package [`RestSharp.Serializers.NewtonsoftJson`](https://www.nuget.org/packages/RestSharp.Serializers.NewtonsoftJson).
32+
33+
::: warning
34+
Please note that `RestSharp.Newtonsoft.Json` package is not provided by RestSharp, is marked as obsolete on NuGet, and no longer supported by its creator.
35+
:::
36+
37+
Use the extension method provided by the package to configure the client:
38+
39+
```csharp
40+
client.UseNewtonsoftJson();
41+
```
42+
43+
The serializer configures some options by default:
44+
45+
```csharp
46+
JsonSerializerSettings DefaultSettings = new JsonSerializerSettings {
47+
ContractResolver = new CamelCasePropertyNamesContractResolver(),
48+
DefaultValueHandling = DefaultValueHandling.Include,
49+
TypeNameHandling = TypeNameHandling.None,
50+
NullValueHandling = NullValueHandling.Ignore,
51+
Formatting = Formatting.None,
52+
ConstructorHandling = ConstructorHandling.AllowNonPublicDefaultConstructor
53+
};
54+
```
55+
56+
If you need to use different settings, you can supply your instance of
57+
`JsonSerializerSettings` as a parameter for the extension method.
58+
59+
## Custom
60+
61+
You can also implement your custom serializer. To support both serialization and
62+
deserialization, you must implement the `IRestSerializer` interface.
63+
64+
Here is an example of a custom serializer that uses `System.Text.Json`:
65+
66+
```csharp
67+
public class SimpleJsonSerializer : IRestSerializer {
68+
public string Serialize(object obj) => JsonSerializer.Serialize(obj);
69+
70+
public string Serialize(Parameter bodyParameter) => Serialize(bodyParameter.Value);
71+
72+
public T Deserialize<T>(IRestResponse response) => JsonSerializer.Deserialize<T>(response.Content);
73+
74+
public string[] SupportedContentTypes { get; } = {
75+
"application/json", "text/json", "text/x-json", "text/javascript", "*+json"
76+
};
77+
78+
public string ContentType { get; set; } = "application/json";
79+
80+
public DataFormat DataFormat { get; } = DataFormat.Json;
81+
}
82+
```
83+
84+
The value of the `SupportedContentTypes` property will be used to match the
85+
serializer with the response `Content-Type` headers.
86+
87+
The `ContentType` property will be used when making a request so the
88+
server knows how to handle the payload.

0 commit comments

Comments
 (0)