Skip to content

Commit 5589824

Browse files
Fix/csharp reserved headers and file parameter not serialising correctly (OpenAPITools#23593)
* fix: Fixed issue where reserved headers were added to the request instead of the content * fix: Fixed issue where file parameter object is incorrectly JSON serialised * chore: Updated samples based on csharp changes * fix: Moved content header checks to client utils * fix: Fixed reference to new IsContentHeader static method * chore: Added "content-disposition" to content header check * fix: Updated ContentHeaders to be compatible with older versions of .NET
1 parent 2917ce8 commit 5589824

160 files changed

Lines changed: 3446 additions & 983 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

modules/openapi-generator/src/main/resources/csharp/libraries/generichost/ClientUtils.mustache

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -407,6 +407,35 @@ using System.Net.Http.Headers;
407407
throw new JsonException("The specified discriminator was not found.");
408408
}
409409

410+
/// <summary>
411+
/// Determines if the provided header is a content header
412+
/// </summary>
413+
/// <param name="header">The header to check</param>
414+
/// <returns>True if a content header; False otherwise</returns>
415+
public static bool IsContentHeader(string header)
416+
{
417+
return ContentHeaders.Contains(header.ToLowerInvariant());
418+
}
419+
420+
/// <summary>
421+
/// The collection of content headers as per
422+
/// https://learn.microsoft.com/en-us/dotnet/api/system.net.http.httpcontent.headers
423+
/// </summary>
424+
private static readonly string[] ContentHeaders = new String[]
425+
{
426+
"allow",
427+
"content-encoding",
428+
"content-disposition",
429+
"content-language",
430+
"content-length",
431+
"content-location",
432+
"content-md5",
433+
"content-range",
434+
"content-type",
435+
"expires",
436+
"last-modified"
437+
};
438+
410439
/// <summary>
411440
/// The base path of the API
412441
/// </summary>

modules/openapi-generator/src/main/resources/csharp/libraries/generichost/api.mustache

Lines changed: 53 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -452,23 +452,6 @@ namespace {{packageName}}.{{apiPackage}}
452452

453453
{{/-last}}
454454
{{/queryParams}}
455-
{{#constantParams}}
456-
{{#isHeaderParam}}
457-
// Set client side default value of Header Param "{{baseName}}".
458-
httpRequestMessageLocalVar.Headers.Add("{{baseName}}", ClientUtils.ParameterToString({{#_enum}}"{{{.}}}"{{/_enum}})); // Constant header parameter
459-
{{/isHeaderParam}}
460-
{{/constantParams}}
461-
{{#headerParams}}
462-
{{#required}}
463-
httpRequestMessageLocalVar.Headers.Add("{{baseName}}", ClientUtils.ParameterToString({{paramName}}));
464-
465-
{{/required}}
466-
{{^required}}
467-
if ({{paramName}}.IsSet)
468-
httpRequestMessageLocalVar.Headers.Add("{{baseName}}", ClientUtils.ParameterToString({{paramName}}.Value));
469-
470-
{{/required}}
471-
{{/headerParams}}
472455
{{#formParams}}
473456
{{#-first}}
474457
{{#isMultipart}}
@@ -561,18 +544,65 @@ namespace {{packageName}}.{{apiPackage}}
561544
{{/formParams}}
562545
{{#bodyParam}}
563546
{{#required}}
564-
httpRequestMessageLocalVar.Content = ({{paramName}}{{^required}}.Value{{/required}} as object) is System.IO.Stream stream
565-
? httpRequestMessageLocalVar.Content = new StreamContent(stream)
547+
httpRequestMessageLocalVar.Content = ({{paramName}}{{^required}}.Value{{/required}} as object) is {{packageName}}.{{clientPackage}}.FileParameter fileParameterLocalVar
548+
? httpRequestMessageLocalVar.Content = new StreamContent(fileParameterLocalVar.Content)
566549
: httpRequestMessageLocalVar.Content = new StringContent(JsonSerializer.Serialize({{paramName}}{{^required}}.Value{{/required}}, _jsonSerializerOptions));
567550
{{/required}}
568551
{{^required}}
569552
if ({{paramName}}.IsSet)
570-
httpRequestMessageLocalVar.Content = ({{paramName}}{{^required}}.Value{{/required}} as object) is System.IO.Stream stream
571-
? httpRequestMessageLocalVar.Content = new StreamContent(stream)
572-
: httpRequestMessageLocalVar.Content = new StringContent(JsonSerializer.Serialize({{paramName}}{{^required}}.Value{{/required}}, _jsonSerializerOptions));
553+
{
554+
httpRequestMessageLocalVar.Content = ({{paramName}}{{^required}}.Value{{/required}} as object) is {{packageName}}.{{clientPackage}}.FileParameter fileParameterLocalVar
555+
? httpRequestMessageLocalVar.Content = new StreamContent(fileParameterLocalVar.Content)
556+
: httpRequestMessageLocalVar.Content = new StringContent(JsonSerializer.Serialize({{paramName}}{{^required}}.Value{{/required}}, _jsonSerializerOptions));
557+
}
573558
{{/required}}
574559

575560
{{/bodyParam}}
561+
562+
{{#constantParams}}
563+
{{#isHeaderParam}}
564+
// Set client side default value of Header Param "{{baseName}}".
565+
if (ClientUtils.IsContentHeader("{{baseName}}"))
566+
{
567+
httpRequestMessageLocalVar.Content.Headers.Add("{{baseName}}", ClientUtils.ParameterToString({{#_enum}}"{{{.}}}"{{/_enum}})); // Constant header parameter
568+
}
569+
else
570+
{
571+
httpRequestMessageLocalVar.Headers.Add("{{baseName}}", ClientUtils.ParameterToString({{#_enum}}"{{{.}}}"{{/_enum}})); // Constant header parameter
572+
}
573+
574+
{{/isHeaderParam}}
575+
{{/constantParams}}
576+
{{#headerParams}}
577+
{{#required}}
578+
// Set client side default value of Header Param "{{baseName}}".
579+
if (ClientUtils.IsContentHeader("{{baseName}}"))
580+
{
581+
httpRequestMessageLocalVar.Content?.Headers.Add("{{baseName}}", ClientUtils.ParameterToString({{paramName}}));
582+
}
583+
else
584+
{
585+
httpRequestMessageLocalVar.Headers.Add("{{baseName}}", ClientUtils.ParameterToString({{paramName}}));
586+
}
587+
588+
{{/required}}
589+
{{^required}}
590+
if ({{paramName}}.IsSet)
591+
{
592+
// Set client side default value of Header Param "{{baseName}}".
593+
if (ClientUtils.IsContentHeader("{{baseName}}"))
594+
{
595+
httpRequestMessageLocalVar.Content?.Headers.Add("{{baseName}}", ClientUtils.ParameterToString({{paramName}}.Value));
596+
}
597+
else
598+
{
599+
httpRequestMessageLocalVar.Headers.Add("{{baseName}}", ClientUtils.ParameterToString({{paramName}}.Value));
600+
}
601+
}
602+
603+
{{/required}}
604+
{{/headerParams}}
605+
576606
{{#authMethods}}
577607
{{#-first}}
578608
List<TokenBase> tokenBaseLocalVars = new List<TokenBase>();
@@ -907,4 +937,4 @@ namespace {{packageName}}.{{apiPackage}}
907937
}
908938
{{/operations}}
909939
}
910-
{{/lambda.trimLineBreaks}}
940+
{{/lambda.trimLineBreaks}}

samples/client/petstore/csharp/generichost/latest/ComposedEnum/src/Org.OpenAPITools/Client/ClientUtils.cs

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -307,6 +307,35 @@ public static bool IsJsonMime(string mime)
307307
throw new JsonException("The specified discriminator was not found.");
308308
}
309309

310+
/// <summary>
311+
/// Determines if the provided header is a content header
312+
/// </summary>
313+
/// <param name="header">The header to check</param>
314+
/// <returns>True if a content header; False otherwise</returns>
315+
public static bool IsContentHeader(string header)
316+
{
317+
return ContentHeaders.Contains(header.ToLowerInvariant());
318+
}
319+
320+
/// <summary>
321+
/// The collection of content headers as per
322+
/// https://learn.microsoft.com/en-us/dotnet/api/system.net.http.httpcontent.headers
323+
/// </summary>
324+
private static readonly string[] ContentHeaders = new String[]
325+
{
326+
"allow",
327+
"content-encoding",
328+
"content-disposition",
329+
"content-language",
330+
"content-length",
331+
"content-location",
332+
"content-md5",
333+
"content-range",
334+
"content-type",
335+
"expires",
336+
"last-modified"
337+
};
338+
310339
/// <summary>
311340
/// The base path of the API
312341
/// </summary>

samples/client/petstore/csharp/generichost/latest/HelloWorld/src/Org.OpenAPITools/Api/DefaultApi.cs

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -249,9 +249,11 @@ public async Task<IHelloWorldPostApiResponse> HelloWorldPostAsync(Option<HelloWo
249249
: string.Concat(HttpClient.BaseAddress.AbsolutePath.TrimEnd('/'), "/helloWorld");
250250

251251
if (helloWorldPostRequest.IsSet)
252-
httpRequestMessageLocalVar.Content = (helloWorldPostRequest.Value as object) is System.IO.Stream stream
253-
? httpRequestMessageLocalVar.Content = new StreamContent(stream)
254-
: httpRequestMessageLocalVar.Content = new StringContent(JsonSerializer.Serialize(helloWorldPostRequest.Value, _jsonSerializerOptions));
252+
{
253+
httpRequestMessageLocalVar.Content = (helloWorldPostRequest.Value as object) is Org.OpenAPITools.Client.FileParameter fileParameterLocalVar
254+
? httpRequestMessageLocalVar.Content = new StreamContent(fileParameterLocalVar.Content)
255+
: httpRequestMessageLocalVar.Content = new StringContent(JsonSerializer.Serialize(helloWorldPostRequest.Value, _jsonSerializerOptions));
256+
}
255257

256258
httpRequestMessageLocalVar.RequestUri = uriBuilderLocalVar.Uri;
257259

samples/client/petstore/csharp/generichost/latest/HelloWorld/src/Org.OpenAPITools/Client/ClientUtils.cs

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -301,6 +301,35 @@ public static bool IsJsonMime(string mime)
301301
throw new JsonException("The specified discriminator was not found.");
302302
}
303303

304+
/// <summary>
305+
/// Determines if the provided header is a content header
306+
/// </summary>
307+
/// <param name="header">The header to check</param>
308+
/// <returns>True if a content header; False otherwise</returns>
309+
public static bool IsContentHeader(string header)
310+
{
311+
return ContentHeaders.Contains(header.ToLowerInvariant());
312+
}
313+
314+
/// <summary>
315+
/// The collection of content headers as per
316+
/// https://learn.microsoft.com/en-us/dotnet/api/system.net.http.httpcontent.headers
317+
/// </summary>
318+
private static readonly string[] ContentHeaders = new String[]
319+
{
320+
"allow",
321+
"content-encoding",
322+
"content-disposition",
323+
"content-language",
324+
"content-length",
325+
"content-location",
326+
"content-md5",
327+
"content-range",
328+
"content-type",
329+
"expires",
330+
"last-modified"
331+
};
332+
304333
/// <summary>
305334
/// The base path of the API
306335
/// </summary>

samples/client/petstore/csharp/generichost/latest/InlineEnumAnyOf/src/Org.OpenAPITools/Client/ClientUtils.cs

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -303,6 +303,35 @@ public static bool IsJsonMime(string mime)
303303
throw new JsonException("The specified discriminator was not found.");
304304
}
305305

306+
/// <summary>
307+
/// Determines if the provided header is a content header
308+
/// </summary>
309+
/// <param name="header">The header to check</param>
310+
/// <returns>True if a content header; False otherwise</returns>
311+
public static bool IsContentHeader(string header)
312+
{
313+
return ContentHeaders.Contains(header.ToLowerInvariant());
314+
}
315+
316+
/// <summary>
317+
/// The collection of content headers as per
318+
/// https://learn.microsoft.com/en-us/dotnet/api/system.net.http.httpcontent.headers
319+
/// </summary>
320+
private static readonly string[] ContentHeaders = new String[]
321+
{
322+
"allow",
323+
"content-encoding",
324+
"content-disposition",
325+
"content-language",
326+
"content-length",
327+
"content-location",
328+
"content-md5",
329+
"content-range",
330+
"content-type",
331+
"expires",
332+
"last-modified"
333+
};
334+
306335
/// <summary>
307336
/// The base path of the API
308337
/// </summary>

samples/client/petstore/csharp/generichost/latest/OneOfList/src/Org.OpenAPITools/Api/DefaultApi.cs

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -230,9 +230,11 @@ public async Task<IOneOfArrayApiResponse> OneOfArrayAsync(Option<OneOfArrayReque
230230
: string.Concat(HttpClient.BaseAddress.AbsolutePath.TrimEnd('/'), "/one-of-array");
231231

232232
if (oneOfArrayRequest.IsSet)
233-
httpRequestMessageLocalVar.Content = (oneOfArrayRequest.Value as object) is System.IO.Stream stream
234-
? httpRequestMessageLocalVar.Content = new StreamContent(stream)
235-
: httpRequestMessageLocalVar.Content = new StringContent(JsonSerializer.Serialize(oneOfArrayRequest.Value, _jsonSerializerOptions));
233+
{
234+
httpRequestMessageLocalVar.Content = (oneOfArrayRequest.Value as object) is Org.OpenAPITools.Client.FileParameter fileParameterLocalVar
235+
? httpRequestMessageLocalVar.Content = new StreamContent(fileParameterLocalVar.Content)
236+
: httpRequestMessageLocalVar.Content = new StringContent(JsonSerializer.Serialize(oneOfArrayRequest.Value, _jsonSerializerOptions));
237+
}
236238

237239
httpRequestMessageLocalVar.RequestUri = uriBuilderLocalVar.Uri;
238240

samples/client/petstore/csharp/generichost/latest/OneOfList/src/Org.OpenAPITools/Client/ClientUtils.cs

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -301,6 +301,35 @@ public static bool IsJsonMime(string mime)
301301
throw new JsonException("The specified discriminator was not found.");
302302
}
303303

304+
/// <summary>
305+
/// Determines if the provided header is a content header
306+
/// </summary>
307+
/// <param name="header">The header to check</param>
308+
/// <returns>True if a content header; False otherwise</returns>
309+
public static bool IsContentHeader(string header)
310+
{
311+
return ContentHeaders.Contains(header.ToLowerInvariant());
312+
}
313+
314+
/// <summary>
315+
/// The collection of content headers as per
316+
/// https://learn.microsoft.com/en-us/dotnet/api/system.net.http.httpcontent.headers
317+
/// </summary>
318+
private static readonly string[] ContentHeaders = new String[]
319+
{
320+
"allow",
321+
"content-encoding",
322+
"content-disposition",
323+
"content-language",
324+
"content-length",
325+
"content-location",
326+
"content-md5",
327+
"content-range",
328+
"content-type",
329+
"expires",
330+
"last-modified"
331+
};
332+
304333
/// <summary>
305334
/// The base path of the API
306335
/// </summary>

samples/client/petstore/csharp/generichost/latest/Tags/src/Org.OpenAPITools/Client/ClientUtils.cs

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -327,6 +327,35 @@ public static bool IsJsonMime(string mime)
327327
throw new JsonException("The specified discriminator was not found.");
328328
}
329329

330+
/// <summary>
331+
/// Determines if the provided header is a content header
332+
/// </summary>
333+
/// <param name="header">The header to check</param>
334+
/// <returns>True if a content header; False otherwise</returns>
335+
public static bool IsContentHeader(string header)
336+
{
337+
return ContentHeaders.Contains(header.ToLowerInvariant());
338+
}
339+
340+
/// <summary>
341+
/// The collection of content headers as per
342+
/// https://learn.microsoft.com/en-us/dotnet/api/system.net.http.httpcontent.headers
343+
/// </summary>
344+
private static readonly string[] ContentHeaders = new String[]
345+
{
346+
"allow",
347+
"content-encoding",
348+
"content-disposition",
349+
"content-language",
350+
"content-length",
351+
"content-location",
352+
"content-md5",
353+
"content-range",
354+
"content-type",
355+
"expires",
356+
"last-modified"
357+
};
358+
330359
/// <summary>
331360
/// The base path of the API
332361
/// </summary>

samples/client/petstore/csharp/generichost/latest/UseDateTimeOffset/src/Org.OpenAPITools/Api/AnotherFakeApi.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -277,8 +277,8 @@ public async Task<ICall123TestSpecialTagsApiResponse> Call123TestSpecialTagsAsyn
277277
? "/another-fake/dummy"
278278
: string.Concat(HttpClient.BaseAddress.AbsolutePath.TrimEnd('/'), "/another-fake/dummy");
279279

280-
httpRequestMessageLocalVar.Content = (modelClient as object) is System.IO.Stream stream
281-
? httpRequestMessageLocalVar.Content = new StreamContent(stream)
280+
httpRequestMessageLocalVar.Content = (modelClient as object) is Org.OpenAPITools.Client.FileParameter fileParameterLocalVar
281+
? httpRequestMessageLocalVar.Content = new StreamContent(fileParameterLocalVar.Content)
282282
: httpRequestMessageLocalVar.Content = new StringContent(JsonSerializer.Serialize(modelClient, _jsonSerializerOptions));
283283

284284
httpRequestMessageLocalVar.RequestUri = uriBuilderLocalVar.Uri;

0 commit comments

Comments
 (0)