From e8ced08ebf613661b44347b682ced7cb3161916d Mon Sep 17 00:00:00 2001 From: HavenDV Date: Sun, 14 Jul 2024 18:41:34 +0400 Subject: [PATCH] fix: Fixed some responses with byte[]. --- src/libs/Directory.Build.props | 2 +- .../OpenApiGenerator.Core/Generation/Data.cs | 3 ++ .../Generation/Sources.Methods.cs | 33 ++++++++++++++----- .../Models/ContentType.cs | 13 ++++++++ .../OpenApiGenerator.Core/Models/EndPoint.cs | 5 +++ ..._#G.AudioClient.CreateSpeech.g.verified.cs | 22 +++---------- ..._#G.AudioClient.CreateSpeech.g.verified.cs | 22 +++---------- .../Snapshots/OpenAi/Methods/_.verified.txt | 1 + 8 files changed, 58 insertions(+), 43 deletions(-) create mode 100644 src/libs/OpenApiGenerator.Core/Models/ContentType.cs diff --git a/src/libs/Directory.Build.props b/src/libs/Directory.Build.props index 926e8515a5..15b6b05b49 100644 --- a/src/libs/Directory.Build.props +++ b/src/libs/Directory.Build.props @@ -39,7 +39,7 @@ - 0.13.4 + 0.13.5 0.1 v dev diff --git a/src/libs/OpenApiGenerator.Core/Generation/Data.cs b/src/libs/OpenApiGenerator.Core/Generation/Data.cs index a2bfc3df1f..b812141fbc 100644 --- a/src/libs/OpenApiGenerator.Core/Generation/Data.cs +++ b/src/libs/OpenApiGenerator.Core/Generation/Data.cs @@ -193,6 +193,7 @@ .. includedTags.Select(x => PropertyData.Default with ] : [], HttpMethod: OperationType.Get, + ContentType: ContentType.String, Summary: openApiDocument.Info?.Description?.ClearForXml() ?? string.Empty, BaseUrlSummary: openApiDocument.Servers!.FirstOrDefault()?.Description?.ClearForXml() ?? string.Empty, Settings: settings, @@ -215,6 +216,7 @@ .. includedTags.Select(x => PropertyData.Default with Path: string.Empty, Properties: ImmutableArray.Empty, HttpMethod: OperationType.Get, + ContentType: ContentType.String, Summary: x.Description?.ClearForXml() ?? string.Empty, BaseUrlSummary: openApiDocument.Servers!.FirstOrDefault()?.Description?.ClearForXml() ?? string.Empty, Settings: settings, @@ -390,6 +392,7 @@ .. includedTags.Select(x => PropertyData.Default with Path: string.Empty, Properties: [], HttpMethod: OperationType.Get, + ContentType: ContentType.String, Summary: string.Empty, BaseUrlSummary: string.Empty, Settings: settings, diff --git a/src/libs/OpenApiGenerator.Core/Generation/Sources.Methods.cs b/src/libs/OpenApiGenerator.Core/Generation/Sources.Methods.cs index ec3d8dc226..37e1f6dd72 100644 --- a/src/libs/OpenApiGenerator.Core/Generation/Sources.Methods.cs +++ b/src/libs/OpenApiGenerator.Core/Generation/Sources.Methods.cs @@ -19,6 +19,12 @@ public static string GenerateEndPoint( var usings = endPoint.Properties.Any(x => x.Type.IsArray && x.ParameterExplode == true) ? "using System.Linq;\n" : ""; + var contentType = endPoint.ContentType switch + { + ContentType.String => "string", + ContentType.Stream => "global::System.IO.Stream", + _ => "byte[]", + }; return $@"{usings} #nullable enable @@ -49,7 +55,7 @@ public partial class {endPoint.ClassName} partial void Process{endPoint.NotAsyncMethodName}ResponseContent( global::System.Net.Http.HttpClient httpClient, global::System.Net.Http.HttpResponseMessage httpResponseMessage, - ref string content);")} + ref {contentType} content);")} {GenerateMethod(endPoint)} {GenerateExtensionMethod(endPoint)} @@ -91,6 +97,12 @@ public static string GenerateMethod( var cancellationTokenInsideReadAsync = endPoint.Settings.TargetFramework.StartsWith("net8", StringComparison.OrdinalIgnoreCase) ? "cancellationToken" : string.Empty; + var contentType = endPoint.ContentType switch + { + ContentType.String => "String", + ContentType.Stream => "Stream", + _ => "ByteArray", + }; return $@" {endPoint.Summary.ToXmlDocumentationSummary(level: 8)} @@ -173,29 +185,34 @@ public static string GenerateMethod( {(string.IsNullOrWhiteSpace(endPoint.ResponseType.CSharpType) || endPoint.Stream ? @" response.EnsureSuccessStatusCode(); " : $@" - var __content = await response.Content.ReadAsStringAsync({cancellationTokenInsideReadAsync}).ConfigureAwait(false); + var __content = await response.Content.ReadAs{contentType}Async({cancellationTokenInsideReadAsync}).ConfigureAwait(false); +{(endPoint.ContentType == ContentType.String ? @" ProcessResponseContent( client: _httpClient, response: response, - content: ref __content); + content: ref __content);" : " ")} Process{endPoint.NotAsyncMethodName}ResponseContent( httpClient: _httpClient, httpResponseMessage: response, content: ref __content); +{(endPoint.ContentType == ContentType.String ? @" try - {{ + { response.EnsureSuccessStatusCode(); - }} + } catch (global::System.Net.Http.HttpRequestException ex) - {{ + { throw new global::System.InvalidOperationException(__content, ex); - }} + }" : @" + response.EnsureSuccessStatusCode();")} +{(endPoint.ContentType == ContentType.String ? $@" return {jsonSerializer.GenerateDeserializeCall(endPoint.ResponseType, endPoint.Settings.JsonSerializerContext)} ?? - throw new global::System.InvalidOperationException($""Response deserialization failed for \""{{__content}}\"" "");")} + throw new global::System.InvalidOperationException($""Response deserialization failed for \""{{__content}}\"" "");" : @" + return __content;")}")} {(endPoint.Stream ? $@" using var stream = await response.Content.ReadAsStreamAsync({cancellationTokenInsideReadAsync}).ConfigureAwait(false); using var reader = new global::System.IO.StreamReader(stream); diff --git a/src/libs/OpenApiGenerator.Core/Models/ContentType.cs b/src/libs/OpenApiGenerator.Core/Models/ContentType.cs new file mode 100644 index 0000000000..e704a0d868 --- /dev/null +++ b/src/libs/OpenApiGenerator.Core/Models/ContentType.cs @@ -0,0 +1,13 @@ +namespace OpenApiGenerator.Core.Models; + +#pragma warning disable CA1720 // Identifier contains type name + +/// +/// HttpContent type. +/// +public enum ContentType +{ + String, + ByteArray, + Stream, +} \ No newline at end of file diff --git a/src/libs/OpenApiGenerator.Core/Models/EndPoint.cs b/src/libs/OpenApiGenerator.Core/Models/EndPoint.cs index ebe3f8d690..99f06b42f4 100644 --- a/src/libs/OpenApiGenerator.Core/Models/EndPoint.cs +++ b/src/libs/OpenApiGenerator.Core/Models/EndPoint.cs @@ -13,6 +13,7 @@ public readonly record struct EndPoint( string Path, ImmutableArray Properties, OperationType HttpMethod, + ContentType ContentType, string Summary, string BaseUrlSummary, Settings Settings, @@ -191,6 +192,10 @@ public static EndPoint FromSchema( Path: preparedPath, Properties: properties.ToImmutableArray(), HttpMethod: operation.Key, + ContentType: responses + .Any(x => x.MediaType.Key.Contains("application/octet-stream")) + ? ContentType.ByteArray + : ContentType.String, Summary: operation.Value.GetXmlDocumentationSummary(), BaseUrlSummary: string.Empty, Settings: settings, diff --git a/src/tests/OpenApiGenerator.SnapshotTests/Snapshots/OpenAi/NewtonsoftJson/_#G.AudioClient.CreateSpeech.g.verified.cs b/src/tests/OpenApiGenerator.SnapshotTests/Snapshots/OpenAi/NewtonsoftJson/_#G.AudioClient.CreateSpeech.g.verified.cs index 96ab58b47a..b0dd2ae781 100644 --- a/src/tests/OpenApiGenerator.SnapshotTests/Snapshots/OpenAi/NewtonsoftJson/_#G.AudioClient.CreateSpeech.g.verified.cs +++ b/src/tests/OpenApiGenerator.SnapshotTests/Snapshots/OpenAi/NewtonsoftJson/_#G.AudioClient.CreateSpeech.g.verified.cs @@ -20,7 +20,7 @@ partial void ProcessCreateSpeechResponse( partial void ProcessCreateSpeechResponseContent( global::System.Net.Http.HttpClient httpClient, global::System.Net.Http.HttpResponseMessage httpResponseMessage, - ref string content); + ref byte[] content); /// /// Generates audio from the input text. @@ -69,29 +69,17 @@ partial void ProcessCreateSpeechResponseContent( httpClient: _httpClient, httpResponseMessage: response); - var __content = await response.Content.ReadAsStringAsync().ConfigureAwait(false); + var __content = await response.Content.ReadAsByteArrayAsync().ConfigureAwait(false); - ProcessResponseContent( - client: _httpClient, - response: response, - content: ref __content); ProcessCreateSpeechResponseContent( httpClient: _httpClient, httpResponseMessage: response, content: ref __content); - try - { - response.EnsureSuccessStatusCode(); - } - catch (global::System.Net.Http.HttpRequestException ex) - { - throw new global::System.InvalidOperationException(__content, ex); - } - return - global::Newtonsoft.Json.JsonConvert.DeserializeObject(__content, _jsonSerializerOptions) ?? - throw new global::System.InvalidOperationException($"Response deserialization failed for \"{__content}\" "); + response.EnsureSuccessStatusCode(); + + return __content; } /// diff --git a/src/tests/OpenApiGenerator.SnapshotTests/Snapshots/OpenAi/SystemTextJson/_#G.AudioClient.CreateSpeech.g.verified.cs b/src/tests/OpenApiGenerator.SnapshotTests/Snapshots/OpenAi/SystemTextJson/_#G.AudioClient.CreateSpeech.g.verified.cs index 4ccebeb552..23cc99bf26 100644 --- a/src/tests/OpenApiGenerator.SnapshotTests/Snapshots/OpenAi/SystemTextJson/_#G.AudioClient.CreateSpeech.g.verified.cs +++ b/src/tests/OpenApiGenerator.SnapshotTests/Snapshots/OpenAi/SystemTextJson/_#G.AudioClient.CreateSpeech.g.verified.cs @@ -20,7 +20,7 @@ partial void ProcessCreateSpeechResponse( partial void ProcessCreateSpeechResponseContent( global::System.Net.Http.HttpClient httpClient, global::System.Net.Http.HttpResponseMessage httpResponseMessage, - ref string content); + ref byte[] content); /// /// Generates audio from the input text. @@ -69,29 +69,17 @@ partial void ProcessCreateSpeechResponseContent( httpClient: _httpClient, httpResponseMessage: response); - var __content = await response.Content.ReadAsStringAsync(cancellationToken).ConfigureAwait(false); + var __content = await response.Content.ReadAsByteArrayAsync(cancellationToken).ConfigureAwait(false); - ProcessResponseContent( - client: _httpClient, - response: response, - content: ref __content); ProcessCreateSpeechResponseContent( httpClient: _httpClient, httpResponseMessage: response, content: ref __content); - try - { - response.EnsureSuccessStatusCode(); - } - catch (global::System.Net.Http.HttpRequestException ex) - { - throw new global::System.InvalidOperationException(__content, ex); - } - return - global::System.Text.Json.JsonSerializer.Deserialize(__content, _jsonSerializerOptions) ?? - throw new global::System.InvalidOperationException($"Response deserialization failed for \"{__content}\" "); + response.EnsureSuccessStatusCode(); + + return __content; } /// diff --git a/src/tests/OpenApiGenerator.UnitTests/Snapshots/OpenAi/Methods/_.verified.txt b/src/tests/OpenApiGenerator.UnitTests/Snapshots/OpenAi/Methods/_.verified.txt index bb49a1eb1a..c3030d6f82 100644 --- a/src/tests/OpenApiGenerator.UnitTests/Snapshots/OpenAi/Methods/_.verified.txt +++ b/src/tests/OpenApiGenerator.UnitTests/Snapshots/OpenAi/Methods/_.verified.txt @@ -3618,6 +3618,7 @@ Default Value: 1, } ], HttpMethod: Post, + ContentType: ByteArray, Summary: Generates audio from the input text., BaseUrlSummary: , Settings: {