forked from loafle/openapi-generator-original
[csharp][csharp-netcore] Fix Fileupload for Request Bodies for RestSharp and HttpClient libraries (#9010)
* Fix Request Body File Upload for RestSharp and csharp-netcore * Update Samples * Fix missing using and update samples * Enable upload test * Fix form data and file upload handling for httpclient, update samples
This commit is contained in:
parent
46326249d2
commit
88fa5d70d7
@ -330,6 +330,20 @@ namespace {{packageName}}.Client
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (options.Data != null)
|
if (options.Data != null)
|
||||||
|
{
|
||||||
|
if (options.Data is Stream stream)
|
||||||
|
{
|
||||||
|
var contentType = "application/octet-stream";
|
||||||
|
if (options.HeaderParameters != null)
|
||||||
|
{
|
||||||
|
var contentTypes = options.HeaderParameters["Content-Type"];
|
||||||
|
contentType = contentTypes[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
var bytes = ClientUtils.ReadAsBytes(stream);
|
||||||
|
request.AddParameter(contentType, bytes, ParameterType.RequestBody);
|
||||||
|
}
|
||||||
|
else
|
||||||
{
|
{
|
||||||
if (options.HeaderParameters != null)
|
if (options.HeaderParameters != null)
|
||||||
{
|
{
|
||||||
@ -351,6 +365,7 @@ namespace {{packageName}}.Client
|
|||||||
|
|
||||||
request.AddJsonBody(options.Data);
|
request.AddJsonBody(options.Data);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (options.FileParameters != null)
|
if (options.FileParameters != null)
|
||||||
{
|
{
|
||||||
|
@ -24,6 +24,7 @@ using ErrorEventArgs = Newtonsoft.Json.Serialization.ErrorEventArgs;
|
|||||||
using System.Net.Http;
|
using System.Net.Http;
|
||||||
{{/useWebRequest}}
|
{{/useWebRequest}}
|
||||||
using System.Net.Http;
|
using System.Net.Http;
|
||||||
|
using System.Net.Http.Headers;
|
||||||
{{#supportsRetry}}
|
{{#supportsRetry}}
|
||||||
using Polly;
|
using Polly;
|
||||||
{{/supportsRetry}}
|
{{/supportsRetry}}
|
||||||
@ -214,6 +215,32 @@ namespace {{packageName}}.Client
|
|||||||
{{/reUseHttpClient}}
|
{{/reUseHttpClient}}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Prepares multipart/form-data content
|
||||||
|
{{! TODO: Add handling of improper usage }}
|
||||||
|
HttpContent PrepareMultipartFormDataContent(RequestOptions options)
|
||||||
|
{
|
||||||
|
string boundary = "---------" + Guid.NewGuid().ToString().ToUpperInvariant();
|
||||||
|
var multipartContent = new MultipartFormDataContent(boundary);
|
||||||
|
foreach (var formParameter in options.FormParameters)
|
||||||
|
{
|
||||||
|
multipartContent.Add(new StringContent(formParameter.Value), formParameter.Key);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (options.FileParameters != null && options.FileParameters.Count > 0)
|
||||||
|
{
|
||||||
|
foreach (var fileParam in options.FileParameters)
|
||||||
|
{
|
||||||
|
var fileStream = fileParam.Value as FileStream;
|
||||||
|
var fileStreamName = fileStream != null ? System.IO.Path.GetFileName(fileStream.Name) : null;
|
||||||
|
var content = new StreamContent(fileParam.Value);
|
||||||
|
content.Headers.ContentType = new MediaTypeHeaderValue("application/octet-stream");
|
||||||
|
multipartContent.Add(content, fileParam.Key,
|
||||||
|
fileStreamName ?? "no_file_name_provided");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return multipartContent;
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Provides all logic for constructing a new HttpRequestMessage.
|
/// Provides all logic for constructing a new HttpRequestMessage.
|
||||||
/// At this point, all information for querying the service is known. Here, it is simply
|
/// At this point, all information for querying the service is known. Here, it is simply
|
||||||
@ -270,51 +297,44 @@ namespace {{packageName}}.Client
|
|||||||
|
|
||||||
List<Tuple<HttpContent, string, string>> contentList = new List<Tuple<HttpContent, string, string>>();
|
List<Tuple<HttpContent, string, string>> contentList = new List<Tuple<HttpContent, string, string>>();
|
||||||
|
|
||||||
if (options.FormParameters != null && options.FormParameters.Count > 0)
|
string contentType = null;
|
||||||
|
if (options.HeaderParameters != null && options.HeaderParameters.ContainsKey("Content-Type"))
|
||||||
{
|
{
|
||||||
contentList.Add(new Tuple<HttpContent, string, string>(new FormUrlEncodedContent(options.FormParameters), null, null));
|
var contentTypes = options.HeaderParameters["Content-Type"];
|
||||||
|
contentType = contentTypes.FirstOrDefault();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
{{!// TODO Add error handling in case of improper usage}}
|
||||||
|
if (contentType == "multipart/form-data")
|
||||||
|
{
|
||||||
|
request.Content = PrepareMultipartFormDataContent(options);
|
||||||
|
}
|
||||||
|
else if (contentType == "application/x-www-form-urlencoded")
|
||||||
|
{
|
||||||
|
request.Content = new FormUrlEncodedContent(options.FormParameters);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
if (options.Data != null)
|
if (options.Data != null)
|
||||||
|
{
|
||||||
|
if (options.Data is Stream s)
|
||||||
|
{
|
||||||
|
contentType ??= "application/octet-stream";
|
||||||
|
|
||||||
|
var streamContent = new StreamContent(s);
|
||||||
|
streamContent.Headers.ContentType = new MediaTypeHeaderValue(contentType);
|
||||||
|
request.Content = streamContent;
|
||||||
|
}
|
||||||
|
else
|
||||||
{
|
{
|
||||||
var serializer = new CustomJsonCodec(SerializerSettings, configuration);
|
var serializer = new CustomJsonCodec(SerializerSettings, configuration);
|
||||||
contentList.Add(
|
request.Content = new StringContent(serializer.Serialize(options.Data), new UTF8Encoding(),
|
||||||
new Tuple<HttpContent, string, string>(new StringContent(serializer.Serialize(options.Data), new UTF8Encoding(), "application/json"), null, null));
|
"application/json");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (options.FileParameters != null && options.FileParameters.Count > 0)
|
|
||||||
{
|
|
||||||
foreach (var fileParam in options.FileParameters)
|
|
||||||
{
|
|
||||||
var bytes = ClientUtils.ReadAsBytes(fileParam.Value);
|
|
||||||
var fileStream = fileParam.Value as FileStream;
|
|
||||||
contentList.Add(new Tuple<HttpContent, string, string>(new ByteArrayContent(bytes), fileParam.Key,
|
|
||||||
fileStream?.Name ?? "no_file_name_provided"));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (contentList.Count > 1)
|
|
||||||
{
|
|
||||||
string boundary = "---------" + Guid.NewGuid().ToString().ToUpperInvariant();
|
|
||||||
var multipartContent = new MultipartFormDataContent(boundary);
|
|
||||||
foreach (var content in contentList)
|
|
||||||
{
|
|
||||||
if(content.Item2 != null)
|
|
||||||
{
|
|
||||||
multipartContent.Add(content.Item1, content.Item2, content.Item3);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
multipartContent.Add(content.Item1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
request.Content = multipartContent;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
request.Content = contentList.FirstOrDefault()?.Item1;
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO provide an alternative that allows cookies per request instead of per API client
|
// TODO provide an alternative that allows cookies per request instead of per API client
|
||||||
if (options.Cookies != null && options.Cookies.Count > 0)
|
if (options.Cookies != null && options.Cookies.Count > 0)
|
||||||
|
@ -284,7 +284,7 @@ namespace Org.OpenAPITools.Test
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Test UploadFile
|
/// Test UploadFile
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[Fact (Skip = "file upload not working for httpclient yet")]
|
[Fact]
|
||||||
public void UploadFileTest()
|
public void UploadFileTest()
|
||||||
{
|
{
|
||||||
Assembly _assembly = Assembly.GetExecutingAssembly();
|
Assembly _assembly = Assembly.GetExecutingAssembly();
|
||||||
|
@ -26,6 +26,7 @@ using Newtonsoft.Json;
|
|||||||
using Newtonsoft.Json.Serialization;
|
using Newtonsoft.Json.Serialization;
|
||||||
using ErrorEventArgs = Newtonsoft.Json.Serialization.ErrorEventArgs;
|
using ErrorEventArgs = Newtonsoft.Json.Serialization.ErrorEventArgs;
|
||||||
using System.Net.Http;
|
using System.Net.Http;
|
||||||
|
using System.Net.Http.Headers;
|
||||||
using Polly;
|
using Polly;
|
||||||
|
|
||||||
namespace Org.OpenAPITools.Client
|
namespace Org.OpenAPITools.Client
|
||||||
@ -202,6 +203,31 @@ namespace Org.OpenAPITools.Client
|
|||||||
_baseUrl = basePath;
|
_baseUrl = basePath;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Prepares multipart/form-data content
|
||||||
|
HttpContent PrepareMultipartFormDataContent(RequestOptions options)
|
||||||
|
{
|
||||||
|
string boundary = "---------" + Guid.NewGuid().ToString().ToUpperInvariant();
|
||||||
|
var multipartContent = new MultipartFormDataContent(boundary);
|
||||||
|
foreach (var formParameter in options.FormParameters)
|
||||||
|
{
|
||||||
|
multipartContent.Add(new StringContent(formParameter.Value), formParameter.Key);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (options.FileParameters != null && options.FileParameters.Count > 0)
|
||||||
|
{
|
||||||
|
foreach (var fileParam in options.FileParameters)
|
||||||
|
{
|
||||||
|
var fileStream = fileParam.Value as FileStream;
|
||||||
|
var fileStreamName = fileStream != null ? System.IO.Path.GetFileName(fileStream.Name) : null;
|
||||||
|
var content = new StreamContent(fileParam.Value);
|
||||||
|
content.Headers.ContentType = new MediaTypeHeaderValue("application/octet-stream");
|
||||||
|
multipartContent.Add(content, fileParam.Key,
|
||||||
|
fileStreamName ?? "no_file_name_provided");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return multipartContent;
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Provides all logic for constructing a new HttpRequestMessage.
|
/// Provides all logic for constructing a new HttpRequestMessage.
|
||||||
/// At this point, all information for querying the service is known. Here, it is simply
|
/// At this point, all information for querying the service is known. Here, it is simply
|
||||||
@ -258,51 +284,43 @@ namespace Org.OpenAPITools.Client
|
|||||||
|
|
||||||
List<Tuple<HttpContent, string, string>> contentList = new List<Tuple<HttpContent, string, string>>();
|
List<Tuple<HttpContent, string, string>> contentList = new List<Tuple<HttpContent, string, string>>();
|
||||||
|
|
||||||
if (options.FormParameters != null && options.FormParameters.Count > 0)
|
string contentType = null;
|
||||||
|
if (options.HeaderParameters != null && options.HeaderParameters.ContainsKey("Content-Type"))
|
||||||
{
|
{
|
||||||
contentList.Add(new Tuple<HttpContent, string, string>(new FormUrlEncodedContent(options.FormParameters), null, null));
|
var contentTypes = options.HeaderParameters["Content-Type"];
|
||||||
|
contentType = contentTypes.FirstOrDefault();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (contentType == "multipart/form-data")
|
||||||
|
{
|
||||||
|
request.Content = PrepareMultipartFormDataContent(options);
|
||||||
|
}
|
||||||
|
else if (contentType == "application/x-www-form-urlencoded")
|
||||||
|
{
|
||||||
|
request.Content = new FormUrlEncodedContent(options.FormParameters);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
if (options.Data != null)
|
if (options.Data != null)
|
||||||
|
{
|
||||||
|
if (options.Data is Stream s)
|
||||||
|
{
|
||||||
|
contentType ??= "application/octet-stream";
|
||||||
|
|
||||||
|
var streamContent = new StreamContent(s);
|
||||||
|
streamContent.Headers.ContentType = new MediaTypeHeaderValue(contentType);
|
||||||
|
request.Content = streamContent;
|
||||||
|
}
|
||||||
|
else
|
||||||
{
|
{
|
||||||
var serializer = new CustomJsonCodec(SerializerSettings, configuration);
|
var serializer = new CustomJsonCodec(SerializerSettings, configuration);
|
||||||
contentList.Add(
|
request.Content = new StringContent(serializer.Serialize(options.Data), new UTF8Encoding(),
|
||||||
new Tuple<HttpContent, string, string>(new StringContent(serializer.Serialize(options.Data), new UTF8Encoding(), "application/json"), null, null));
|
"application/json");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (options.FileParameters != null && options.FileParameters.Count > 0)
|
|
||||||
{
|
|
||||||
foreach (var fileParam in options.FileParameters)
|
|
||||||
{
|
|
||||||
var bytes = ClientUtils.ReadAsBytes(fileParam.Value);
|
|
||||||
var fileStream = fileParam.Value as FileStream;
|
|
||||||
contentList.Add(new Tuple<HttpContent, string, string>(new ByteArrayContent(bytes), fileParam.Key,
|
|
||||||
fileStream?.Name ?? "no_file_name_provided"));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (contentList.Count > 1)
|
|
||||||
{
|
|
||||||
string boundary = "---------" + Guid.NewGuid().ToString().ToUpperInvariant();
|
|
||||||
var multipartContent = new MultipartFormDataContent(boundary);
|
|
||||||
foreach (var content in contentList)
|
|
||||||
{
|
|
||||||
if(content.Item2 != null)
|
|
||||||
{
|
|
||||||
multipartContent.Add(content.Item1, content.Item2, content.Item3);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
multipartContent.Add(content.Item1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
request.Content = multipartContent;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
request.Content = contentList.FirstOrDefault()?.Item1;
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO provide an alternative that allows cookies per request instead of per API client
|
// TODO provide an alternative that allows cookies per request instead of per API client
|
||||||
if (options.Cookies != null && options.Cookies.Count > 0)
|
if (options.Cookies != null && options.Cookies.Count > 0)
|
||||||
|
@ -330,6 +330,20 @@ namespace Org.OpenAPITools.Client
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (options.Data != null)
|
if (options.Data != null)
|
||||||
|
{
|
||||||
|
if (options.Data is Stream stream)
|
||||||
|
{
|
||||||
|
var contentType = "application/octet-stream";
|
||||||
|
if (options.HeaderParameters != null)
|
||||||
|
{
|
||||||
|
var contentTypes = options.HeaderParameters["Content-Type"];
|
||||||
|
contentType = contentTypes[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
var bytes = ClientUtils.ReadAsBytes(stream);
|
||||||
|
request.AddParameter(contentType, bytes, ParameterType.RequestBody);
|
||||||
|
}
|
||||||
|
else
|
||||||
{
|
{
|
||||||
if (options.HeaderParameters != null)
|
if (options.HeaderParameters != null)
|
||||||
{
|
{
|
||||||
@ -351,6 +365,7 @@ namespace Org.OpenAPITools.Client
|
|||||||
|
|
||||||
request.AddJsonBody(options.Data);
|
request.AddJsonBody(options.Data);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (options.FileParameters != null)
|
if (options.FileParameters != null)
|
||||||
{
|
{
|
||||||
|
@ -330,6 +330,20 @@ namespace Org.OpenAPITools.Client
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (options.Data != null)
|
if (options.Data != null)
|
||||||
|
{
|
||||||
|
if (options.Data is Stream stream)
|
||||||
|
{
|
||||||
|
var contentType = "application/octet-stream";
|
||||||
|
if (options.HeaderParameters != null)
|
||||||
|
{
|
||||||
|
var contentTypes = options.HeaderParameters["Content-Type"];
|
||||||
|
contentType = contentTypes[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
var bytes = ClientUtils.ReadAsBytes(stream);
|
||||||
|
request.AddParameter(contentType, bytes, ParameterType.RequestBody);
|
||||||
|
}
|
||||||
|
else
|
||||||
{
|
{
|
||||||
if (options.HeaderParameters != null)
|
if (options.HeaderParameters != null)
|
||||||
{
|
{
|
||||||
@ -351,6 +365,7 @@ namespace Org.OpenAPITools.Client
|
|||||||
|
|
||||||
request.AddJsonBody(options.Data);
|
request.AddJsonBody(options.Data);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (options.FileParameters != null)
|
if (options.FileParameters != null)
|
||||||
{
|
{
|
||||||
|
@ -329,6 +329,20 @@ namespace Org.OpenAPITools.Client
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (options.Data != null)
|
if (options.Data != null)
|
||||||
|
{
|
||||||
|
if (options.Data is Stream stream)
|
||||||
|
{
|
||||||
|
var contentType = "application/octet-stream";
|
||||||
|
if (options.HeaderParameters != null)
|
||||||
|
{
|
||||||
|
var contentTypes = options.HeaderParameters["Content-Type"];
|
||||||
|
contentType = contentTypes[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
var bytes = ClientUtils.ReadAsBytes(stream);
|
||||||
|
request.AddParameter(contentType, bytes, ParameterType.RequestBody);
|
||||||
|
}
|
||||||
|
else
|
||||||
{
|
{
|
||||||
if (options.HeaderParameters != null)
|
if (options.HeaderParameters != null)
|
||||||
{
|
{
|
||||||
@ -350,6 +364,7 @@ namespace Org.OpenAPITools.Client
|
|||||||
|
|
||||||
request.AddJsonBody(options.Data);
|
request.AddJsonBody(options.Data);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (options.FileParameters != null)
|
if (options.FileParameters != null)
|
||||||
{
|
{
|
||||||
|
@ -330,6 +330,20 @@ namespace Org.OpenAPITools.Client
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (options.Data != null)
|
if (options.Data != null)
|
||||||
|
{
|
||||||
|
if (options.Data is Stream stream)
|
||||||
|
{
|
||||||
|
var contentType = "application/octet-stream";
|
||||||
|
if (options.HeaderParameters != null)
|
||||||
|
{
|
||||||
|
var contentTypes = options.HeaderParameters["Content-Type"];
|
||||||
|
contentType = contentTypes[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
var bytes = ClientUtils.ReadAsBytes(stream);
|
||||||
|
request.AddParameter(contentType, bytes, ParameterType.RequestBody);
|
||||||
|
}
|
||||||
|
else
|
||||||
{
|
{
|
||||||
if (options.HeaderParameters != null)
|
if (options.HeaderParameters != null)
|
||||||
{
|
{
|
||||||
@ -351,6 +365,7 @@ namespace Org.OpenAPITools.Client
|
|||||||
|
|
||||||
request.AddJsonBody(options.Data);
|
request.AddJsonBody(options.Data);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (options.FileParameters != null)
|
if (options.FileParameters != null)
|
||||||
{
|
{
|
||||||
|
Loading…
x
Reference in New Issue
Block a user