Skip to content

Commit fef25a5

Browse files
Allow setting parameter content type (#2249)
* Allow setting parameter content type * Added a test * Add docs
1 parent 4ddda24 commit fef25a5

File tree

3 files changed

+77
-7
lines changed

3 files changed

+77
-7
lines changed

docs/docs/usage/request.md

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,11 +71,30 @@ request.AddParameter("name", "Væ üé", false); // don't encode the value
7171
If you have files, RestSharp will send a `multipart/form-data` request. Your parameters will be part of this request in the form:
7272

7373
```
74+
Content-Type: text/plain; charset=utf-8
7475
Content-Disposition: form-data; name="parameterName"
7576
7677
ParameterValue
7778
```
7879

80+
Sometimes, you need to override the default content type for the parameter when making a multipart form call. It's possible to do by setting the `ContentType` property of the parameter object. As an example, the code below will create a POST parameter with JSON value, and set the appropriate content type:
81+
82+
```csharp
83+
var parameter = new GetOrPostParameter("someJson", "{\"attributeFormat\":\"pdf\"}") {
84+
ContentType = "application/json"
85+
};
86+
request.AddParameter(parameter);
87+
```
88+
89+
When the request is set to use multipart content, the parameter will be sent as part of the request with the specified content type:
90+
91+
```
92+
Content-Type: application/json; charset=utf-8
93+
Content-Disposition: form-data; name="someJson"
94+
95+
{"attributeFormat":"pdf"}
96+
```
97+
7998
You can also add `GetOrPost` parameter as a default parameter to the client. This will add the parameter to every request made by the client.
8099

81100
```csharp

src/RestSharp/Parameters/Parameter.cs

Lines changed: 31 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -32,13 +32,29 @@ protected Parameter(string? name, object? value, ParameterType type, bool encode
3232
}
3333

3434
/// <summary>
35-
/// MIME content type of the parameter
35+
/// Content type of the parameter. Normally applies to the body parameter, or POST parameter in multipart requests.
3636
/// </summary>
37-
public ContentType ContentType { get; protected init; } = ContentType.Undefined;
38-
public string? Name { get; }
39-
public object? Value { get; }
40-
public ParameterType Type { get; }
41-
public bool Encode { get; }
37+
public ContentType ContentType { get; set; } = ContentType.Undefined;
38+
39+
/// <summary>
40+
/// Parameter name
41+
/// </summary>
42+
public string? Name { get; }
43+
44+
/// <summary>
45+
/// Parameter value
46+
/// </summary>
47+
public object? Value { get; }
48+
49+
/// <summary>
50+
/// Parameter type
51+
/// </summary>
52+
public ParameterType Type { get; }
53+
54+
/// <summary>
55+
/// Indicates if the parameter value should be encoded or not.
56+
/// </summary>
57+
public bool Encode { get; }
4258

4359
/// <summary>
4460
/// Return a human-readable representation of this parameter
@@ -48,6 +64,15 @@ protected Parameter(string? name, object? value, ParameterType type, bool encode
4864

4965
protected virtual string ValueString => Value?.ToString() ?? "null";
5066

67+
/// <summary>
68+
/// Creates a parameter object of based on the type
69+
/// </summary>
70+
/// <param name="name">Parameter name</param>
71+
/// <param name="value">Parameter value</param>
72+
/// <param name="type">Parameter type</param>
73+
/// <param name="encode">Indicates if the parameter value should be encoded</param>
74+
/// <returns></returns>
75+
/// <exception cref="ArgumentOutOfRangeException"></exception>
5176
public static Parameter CreateParameter(string? name, object? value, ParameterType type, bool encode = true)
5277
// ReSharper disable once SwitchExpressionHandlesSomeKnownEnumValuesWithExceptionInDefault
5378
=> type switch {

test/RestSharp.Tests.Integrated/MultipartFormDataTests.cs

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ public MultipartFormDataTests(ITestOutputHelper output) {
1313
_server = WireMockServer.Start();
1414

1515
_capturer = _server.ConfigureBodyCapturer(Method.Post);
16+
1617
var options = new RestClientOptions($"{_server.Url!}{RequestBodyCapturer.Resource}") {
1718
ConfigureMessageHandler = handler => new HttpTracerHandler(handler, new OutputLogger(output), HttpMessageParts.All)
1819
};
@@ -180,7 +181,7 @@ public async Task MultipartFormDataAsync() {
180181

181182
_capturer.Body.Should().Be(expected);
182183
}
183-
184+
184185
[Fact]
185186
public async Task MultipartFormData_Without_File_Creates_A_Valid_RequestBody() {
186187
using var client = new RestClient(_server.Url!);
@@ -206,4 +207,29 @@ public async Task MultipartFormData_Without_File_Creates_A_Valid_RequestBody() {
206207
var actual = capturer.Body!.Replace("\n", string.Empty).Split('\r');
207208
actual.Should().Contain(expectedBody);
208209
}
210+
211+
[Fact]
212+
public async Task PostParameter_contentType_in_multipart_form() {
213+
using var client = new RestClient(_server.Url!);
214+
215+
var request = new RestRequest(RequestBodyCapturer.Resource, Method.Post) {
216+
AlwaysMultipartFormData = true
217+
};
218+
var capturer = _server.ConfigureBodyCapturer(Method.Post);
219+
220+
const string parameterName = "Arequest";
221+
const string parameterValue = "{\"attributeFormat\":\"pdf\"}";
222+
223+
var parameter = new GetOrPostParameter(parameterName, parameterValue) {
224+
ContentType = "application/json"
225+
};
226+
request.AddParameter(parameter);
227+
228+
await client.ExecuteAsync(request);
229+
230+
var actual = capturer.Body!.Replace("\n", string.Empty).Split('\r');
231+
actual[1].Should().Be("Content-Type: application/json; charset=utf-8");
232+
actual[2].Should().Be($"Content-Disposition: form-data; name={parameterName}");
233+
actual[4].Should().Be(parameterValue);
234+
}
209235
}

0 commit comments

Comments
 (0)