-
-
Notifications
You must be signed in to change notification settings - Fork 2.3k
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
Make parameters order in a post query configurable #2098
Comments
It can be done that parameters are added to the request in the same order as they are added to The cross-type parameter order is an issue with current implementation as RestSharp adds them by parameter type (all POST parameters, all files, etc), so order between parameter types is not kept. It can be solved, but it means that the request builder needs to be rebuilt. |
It's exactly that. In your case we need to have files at the end and POST parameters in first places.
To do that, we indeed have to rebuild the query builder or allow to use a different query builder. |
I think the solution should be to do that rewrite I mentioned. |
Here's my use case for the reference: the web server requires files to go after other parameters in multipart POST requests. Meanwhile, RestSharp 110.2.0 adds files first. My workaround is to reorder content manually in request.OnBeforeRequest += message =>
{
if (message.Content is MultipartFormDataContent oldContent)
{
var newContent = new MultipartFormDataContent(
oldContent.Headers.ContentType?.Parameters?.FirstOrDefault(p => p.Name == "boundary")?.Value
?? "---" + Guid.NewGuid().ToString("N"));
foreach (var c in oldContent.OrderBy(content => content is StreamContent ? 1 : 0))
{
newContent.Add(c);
}
message.Content = newContent;
}
return ValueTask.CompletedTask;
}; |
if it helps anyone, I was able to find a solution as follows. |
I've taken @paul-sh 's approach and made a hack to provide a solution for @Ducatel 's problem (while @b166er 's way can fix most APIs) You need to use my request.AddParameter("Payload1", "{ \"x\" : \"y\" }");
request.AddFileAtIndex("File1", new byte[3] { 1, 2, 3 }, "xyz1.pdf");
request.AddFileAtIndex("File2", new byte[3] { 1, 2, 3 }, "xyz2.pdf");
request.AddParameter("Payload2", "{ \"x\" : \"y\" }");
request.AddFileAtIndex("File3", new byte[3] { 1, 2, 3 }, "xyz3.pdf");
request.AddHeader("Content-Type", "multipart/form-data");
request.AlwaysMultipartFormData = true; The implementation is done in a class extension for RestRequest: namespace RestSharp
{
public static partial class RestRequestFileIndexExtensions
{
public const string FileIndexParameterNamePrefix = "$RestSharpAddFile_";
public static RestRequest AddFileAtIndex(
this RestRequest request,
string name,
string path,
ContentType contentType = null,
FileParameterOptions options = null
)
{
request = request.AddFile(name, path, contentType, options);
request = request.AddParameter(FileIndexParameterNamePrefix + (request.Files.Count - 1).ToString(CultureInfo.InvariantCulture), @"");
request.OnBeforeRequest -= OnBeforeRequestAddFileIndex;
request.OnBeforeRequest += OnBeforeRequestAddFileIndex;
return request;
}
public static RestRequest AddFileAtIndex(
this RestRequest request,
string name,
byte[] bytes,
string fileName,
ContentType contentType = null,
FileParameterOptions options = null
)
{
request = request.AddFile(name, bytes, fileName, contentType, options);
request = request.AddParameter(FileIndexParameterNamePrefix + (request.Files.Count - 1).ToString(CultureInfo.InvariantCulture), @"");
request.OnBeforeRequest -= OnBeforeRequestAddFileIndex;
request.OnBeforeRequest += OnBeforeRequestAddFileIndex;
return request;
}
public static RestRequest AddFileAtIndex(
this RestRequest request,
string name,
Func<Stream> getFile,
string fileName,
ContentType contentType = null,
FileParameterOptions options = null
)
{
request = request.AddFile(name, getFile, fileName, contentType, options);
request = request.AddParameter(FileIndexParameterNamePrefix + (request.Files.Count - 1).ToString(CultureInfo.InvariantCulture), @"");
request.OnBeforeRequest -= OnBeforeRequestAddFileIndex;
request.OnBeforeRequest += OnBeforeRequestAddFileIndex;
return request;
}
public static Func<HttpRequestMessage, ValueTask> OnBeforeRequestAddFileIndex = message =>
{
if (message.Content is MultipartFormDataContent oldContent)
{
var newContent = new MultipartFormDataContent(
oldContent.Headers.ContentType?.Parameters?.FirstOrDefault(p => p.Name == "boundary")?.Value?.Trim('"')
?? "---" + Guid.NewGuid().ToString("N"));
var streamContentList = oldContent.Where(content => content is StreamContent).ToList();
foreach (var c in oldContent.Where(content => !(content is StreamContent)))
{
if (c.Headers.ContentDisposition.Name.StartsWith(FileIndexParameterNamePrefix))
{
int index = int.Parse(c.Headers.ContentDisposition.Name.Substring(FileIndexParameterNamePrefix.Length), CultureInfo.InvariantCulture);
newContent.Add(streamContentList[index]);
}
else
{
newContent.Add(c);
}
}
message.Content = newContent;
}
return new ValueTask(Task.Delay(0));
};
}
} |
I believe it's all fixable in RestSharp, but it requires a complete rewrite of the |
Hi,
has already mention in this issue #1937
I create this issue to speak about technical solution I will PR.
Is your feature request related to a problem? Please describe.
Some API require an exact order of fields in POST multipart formdata.
I the actual behavior the file is always put in first.
Describe the solution you'd like
Make fields order parametable for each request.
To do that, I plan to add in RestRequest an array of 3 Enum value (like
ParameterType.File
,ParameterType.Body
,ParameterType.Post
) which will define the order. (Maybe the enum already exist ? I don't really search for yet )The default order will be the actual one [File, body, post] to not break existing code.
In the
RequestContent.BuildContent
I will use this array to re-order call from line 46 to 53 (maybe will add headers in the list also, not sure yet)Do you thinks this can be a good solution ? Or do you have better idea ?
Describe alternatives you've considered
No work around found
The text was updated successfully, but these errors were encountered: