Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow setting parameter content type #2249

Merged
merged 3 commits into from
Jul 30, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 19 additions & 0 deletions docs/docs/usage/request.md
Original file line number Diff line number Diff line change
Expand Up @@ -71,11 +71,30 @@ request.AddParameter("name", "Væ üé", false); // don't encode the value
If you have files, RestSharp will send a `multipart/form-data` request. Your parameters will be part of this request in the form:

```
Content-Type: text/plain; charset=utf-8
Content-Disposition: form-data; name="parameterName"

ParameterValue
```

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:

```csharp
var parameter = new GetOrPostParameter("someJson", "{\"attributeFormat\":\"pdf\"}") {
ContentType = "application/json"
};
request.AddParameter(parameter);
```

When the request is set to use multipart content, the parameter will be sent as part of the request with the specified content type:

```
Content-Type: application/json; charset=utf-8
Content-Disposition: form-data; name="someJson"

{"attributeFormat":"pdf"}
```

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.

```csharp
Expand Down
37 changes: 31 additions & 6 deletions src/RestSharp/Parameters/Parameter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -32,13 +32,29 @@ protected Parameter(string? name, object? value, ParameterType type, bool encode
}

/// <summary>
/// MIME content type of the parameter
/// Content type of the parameter. Normally applies to the body parameter, or POST parameter in multipart requests.
/// </summary>
public ContentType ContentType { get; protected init; } = ContentType.Undefined;
public string? Name { get; }
public object? Value { get; }
public ParameterType Type { get; }
public bool Encode { get; }
public ContentType ContentType { get; set; } = ContentType.Undefined;

/// <summary>
/// Parameter name
/// </summary>
public string? Name { get; }

/// <summary>
/// Parameter value
/// </summary>
public object? Value { get; }

/// <summary>
/// Parameter type
/// </summary>
public ParameterType Type { get; }

/// <summary>
/// Indicates if the parameter value should be encoded or not.
/// </summary>
public bool Encode { get; }

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

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

/// <summary>
/// Creates a parameter object of based on the type
/// </summary>
/// <param name="name">Parameter name</param>
/// <param name="value">Parameter value</param>
/// <param name="type">Parameter type</param>
/// <param name="encode">Indicates if the parameter value should be encoded</param>
/// <returns></returns>
/// <exception cref="ArgumentOutOfRangeException"></exception>
public static Parameter CreateParameter(string? name, object? value, ParameterType type, bool encode = true)
// ReSharper disable once SwitchExpressionHandlesSomeKnownEnumValuesWithExceptionInDefault
=> type switch {
Expand Down
28 changes: 27 additions & 1 deletion test/RestSharp.Tests.Integrated/MultipartFormDataTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ public MultipartFormDataTests(ITestOutputHelper output) {
_server = WireMockServer.Start();

_capturer = _server.ConfigureBodyCapturer(Method.Post);

var options = new RestClientOptions($"{_server.Url!}{RequestBodyCapturer.Resource}") {
ConfigureMessageHandler = handler => new HttpTracerHandler(handler, new OutputLogger(output), HttpMessageParts.All)
};
Expand Down Expand Up @@ -180,7 +181,7 @@ public async Task MultipartFormDataAsync() {

_capturer.Body.Should().Be(expected);
}

[Fact]
public async Task MultipartFormData_Without_File_Creates_A_Valid_RequestBody() {
using var client = new RestClient(_server.Url!);
Expand All @@ -206,4 +207,29 @@ public async Task MultipartFormData_Without_File_Creates_A_Valid_RequestBody() {
var actual = capturer.Body!.Replace("\n", string.Empty).Split('\r');
actual.Should().Contain(expectedBody);
}

[Fact]
public async Task PostParameter_contentType_in_multipart_form() {
using var client = new RestClient(_server.Url!);

var request = new RestRequest(RequestBodyCapturer.Resource, Method.Post) {
AlwaysMultipartFormData = true
};
var capturer = _server.ConfigureBodyCapturer(Method.Post);

const string parameterName = "Arequest";
const string parameterValue = "{\"attributeFormat\":\"pdf\"}";

var parameter = new GetOrPostParameter(parameterName, parameterValue) {
ContentType = "application/json"
};
request.AddParameter(parameter);

await client.ExecuteAsync(request);

var actual = capturer.Body!.Replace("\n", string.Empty).Split('\r');
actual[1].Should().Be("Content-Type: application/json; charset=utf-8");
actual[2].Should().Be($"Content-Disposition: form-data; name={parameterName}");
actual[4].Should().Be(parameterValue);
}
}
Loading