Skip to content

Commit 4b88cf8

Browse files
[REQ][CSHARP][GENERICHOST] Support stream for binary response (#21677)
* Add ContentStream property to ApiResponse * Add a constructor which sets ContentStream * Create and use a memory stream for binary model types * Remove extra space * Update samples * Add {{nrt?}} to support older versions * Remove public modifier for interface property
1 parent 8874df4 commit 4b88cf8

File tree

155 files changed

+18144
-3250
lines changed

Some content is hidden

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

155 files changed

+18144
-3250
lines changed

modules/openapi-generator/src/main/resources/csharp/libraries/generichost/ApiResponse`1.mustache

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,11 @@ namespace {{packageName}}.{{clientPackage}}
3333
/// The raw content of this response.
3434
/// </summary>
3535
string RawContent { get; }
36+
37+
/// <summary>
38+
/// The raw binary stream (only set for binary responses)
39+
/// </summary>
40+
System.IO.Stream{{nrt?}} ContentStream { get; }
3641

3742
/// <summary>
3843
/// The DateTime when the request was retrieved.
@@ -81,6 +86,11 @@ namespace {{packageName}}.{{clientPackage}}
8186
/// </summary>
8287
public string RawContent { get; protected set; }
8388

89+
/// <summary>
90+
/// The raw binary stream (only set for binary responses)
91+
/// </summary>
92+
public System.IO.Stream{{nrt?}} ContentStream { get; protected set; }
93+
8494
/// <summary>
8595
/// The IsSuccessStatusCode from the api response
8696
/// </summary>
@@ -144,6 +154,30 @@ namespace {{packageName}}.{{clientPackage}}
144154
OnCreated(httpRequestMessage, httpResponseMessage);
145155
}
146156

157+
/// <summary>
158+
/// Construct the response using an HttpResponseMessage
159+
/// </summary>
160+
/// <param name="httpRequestMessage"></param>
161+
/// <param name="httpResponseMessage"></param>
162+
/// <param name="contentStream"></param>
163+
/// <param name="path"></param>
164+
/// <param name="requestedAt"></param>
165+
/// <param name="jsonSerializerOptions"></param>
166+
public ApiResponse(global::System.Net.Http.HttpRequestMessage httpRequestMessage, System.Net.Http.HttpResponseMessage httpResponseMessage, System.IO.Stream contentStream, string path, DateTime requestedAt, System.Text.Json.JsonSerializerOptions jsonSerializerOptions)
167+
{
168+
StatusCode = httpResponseMessage.StatusCode;
169+
Headers = httpResponseMessage.Headers;
170+
IsSuccessStatusCode = httpResponseMessage.IsSuccessStatusCode;
171+
ReasonPhrase = httpResponseMessage.ReasonPhrase;
172+
ContentStream = contentStream;
173+
RawContent = string.Empty;
174+
Path = path;
175+
RequestUri = httpRequestMessage.RequestUri;
176+
RequestedAt = requestedAt;
177+
_jsonSerializerOptions = jsonSerializerOptions;
178+
OnCreated(httpRequestMessage, httpResponseMessage);
179+
}
180+
147181
partial void OnCreated(global::System.Net.Http.HttpRequestMessage httpRequestMessage, System.Net.Http.HttpResponseMessage httpResponseMessage);
148182
}
149183
{{#x-http-statuses-with-return}}
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
11
// This logic may be modified with the AsModel.mustache template
22
return Is{{vendorExtensions.x-http-status}}
3-
? System.Text.Json.JsonSerializer.Deserialize<{{#isModel}}{{^containerType}}{{packageName}}.{{modelPackage}}.{{/containerType}}{{/isModel}}{{{dataType}}}>(RawContent, _jsonSerializerOptions)
3+
? {{#isBinary}}ContentStream{{/isBinary}}{{^isBinary}}System.Text.Json.JsonSerializer.Deserialize<{{#isModel}}{{^containerType}}{{packageName}}.{{modelPackage}}.{{/containerType}}{{/isModel}}{{{dataType}}}>(RawContent, _jsonSerializerOptions){{/isBinary}}
44
: {{#net60OrLater}}null{{/net60OrLater}}{{^net60OrLater}}default{{/net60OrLater}};

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

Lines changed: 43 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -291,7 +291,6 @@ namespace {{packageName}}.{{apiPackage}}
291291
bool suppressDefaultLog = false;
292292
After{{operationId}}({{#lambda.joinWithComma}}ref suppressDefaultLog apiResponseLocalVar {{#allParams}}{{paramName}} {{/allParams}}{{/lambda.joinWithComma}});
293293
{{>AfterOperationDefaultImplementation}}
294-
295294
}
296295

297296
/// <summary>
@@ -624,11 +623,35 @@ namespace {{packageName}}.{{apiPackage}}
624623

625624
using (HttpResponseMessage httpResponseMessageLocalVar = await HttpClient.SendAsync(httpRequestMessageLocalVar, cancellationToken).ConfigureAwait(false))
626625
{
627-
string responseContentLocalVar = await httpResponseMessageLocalVar.Content.ReadAsStringAsync({{#net60OrLater}}cancellationToken{{/net60OrLater}}).ConfigureAwait(false);
628-
629626
ILogger<{{#vendorExtensions.x-duplicates}}{{.}}.{{/vendorExtensions.x-duplicates}}{{operationId}}ApiResponse> apiResponseLoggerLocalVar = LoggerFactory.CreateLogger<{{#vendorExtensions.x-duplicates}}{{.}}.{{/vendorExtensions.x-duplicates}}{{operationId}}ApiResponse>();
627+
{{#vendorExtensions.x-duplicates}}{{.}}.{{/vendorExtensions.x-duplicates}}{{operationId}}ApiResponse apiResponseLocalVar;
628+
629+
switch ((int)httpResponseMessageLocalVar.StatusCode) {
630+
{{#responses}}
631+
{{#isBinary}}
632+
case ({{code}}):
633+
{{/isBinary}}
634+
{{/responses}}
635+
{{#responses}}
636+
{{#isBinary}}
637+
{{#-first}}
638+
{
639+
byte[] responseBytesArrayLocalVar = await httpResponseMessageLocalVar.Content.ReadAsByteArrayAsync({{#net60OrLater}}cancellationToken{{/net60OrLater}}).ConfigureAwait(false);
640+
System.IO.Stream responseContentStreamLocalVar = new System.IO.MemoryStream(responseBytesArrayLocalVar);
641+
apiResponseLocalVar = new{{^net60OrLater}} {{operationId}}ApiResponse{{/net60OrLater}}(apiResponseLoggerLocalVar, httpRequestMessageLocalVar, httpResponseMessageLocalVar, responseContentStreamLocalVar, "{{{path}}}", requestedAtLocalVar, _jsonSerializerOptions);
630642

631-
{{#vendorExtensions.x-duplicates}}{{.}}.{{/vendorExtensions.x-duplicates}}{{operationId}}ApiResponse apiResponseLocalVar = new{{^net60OrLater}} {{operationId}}ApiResponse{{/net60OrLater}}(apiResponseLoggerLocalVar, httpRequestMessageLocalVar, httpResponseMessageLocalVar, responseContentLocalVar, "{{{path}}}", requestedAtLocalVar, _jsonSerializerOptions);
643+
break;
644+
}
645+
{{/-first}}
646+
{{/isBinary}}
647+
{{/responses}}
648+
default: {
649+
string responseContentLocalVar = await httpResponseMessageLocalVar.Content.ReadAsStringAsync({{#net60OrLater}}cancellationToken{{/net60OrLater}}).ConfigureAwait(false);
650+
apiResponseLocalVar = new{{^net60OrLater}} {{operationId}}ApiResponse{{/net60OrLater}}(apiResponseLoggerLocalVar, httpRequestMessageLocalVar, httpResponseMessageLocalVar, responseContentLocalVar, "{{{path}}}", requestedAtLocalVar, _jsonSerializerOptions);
651+
652+
break;
653+
}
654+
}
632655

633656
After{{operationId}}DefaultImplementation({{#lambda.joinWithComma}}apiResponseLocalVar {{#allParams}}{{paramName}} {{/allParams}}{{/lambda.joinWithComma}});
634657

@@ -717,6 +740,22 @@ namespace {{packageName}}.{{apiPackage}}
717740
OnCreated(httpRequestMessage, httpResponseMessage);
718741
}
719742

743+
/// <summary>
744+
/// The <see cref="{{operationId}}ApiResponse"/>
745+
/// </summary>
746+
/// <param name="logger"></param>
747+
/// <param name="httpRequestMessage"></param>
748+
/// <param name="httpResponseMessage"></param>
749+
/// <param name="contentStream"></param>
750+
/// <param name="path"></param>
751+
/// <param name="requestedAt"></param>
752+
/// <param name="jsonSerializerOptions"></param>
753+
public {{operationId}}ApiResponse(ILogger<{{operationId}}ApiResponse> logger, System.Net.Http.HttpRequestMessage httpRequestMessage, System.Net.Http.HttpResponseMessage httpResponseMessage, System.IO.Stream contentStream, string path, DateTime requestedAt, System.Text.Json.JsonSerializerOptions jsonSerializerOptions) : base(httpRequestMessage, httpResponseMessage, contentStream, path, requestedAt, jsonSerializerOptions)
754+
{
755+
Logger = logger;
756+
OnCreated(httpRequestMessage, httpResponseMessage);
757+
}
758+
720759
partial void OnCreated(global::System.Net.Http.HttpRequestMessage httpRequestMessage, System.Net.Http.HttpResponseMessage httpResponseMessage);
721760
{{#responses}}
722761

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

Lines changed: 26 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -166,8 +166,7 @@ private void AfterHelloWorldPostDefaultImplementation(IHelloWorldPostApiResponse
166166
bool suppressDefaultLog = false;
167167
AfterHelloWorldPost(ref suppressDefaultLog, apiResponseLocalVar, helloWorldPostRequest);
168168
if (!suppressDefaultLog)
169-
Logger.LogInformation("{0,-9} | {1} | {3}", (apiResponseLocalVar.DownloadedAt - apiResponseLocalVar.RequestedAt).TotalSeconds, apiResponseLocalVar.StatusCode, apiResponseLocalVar.Path);
170-
}
169+
Logger.LogInformation("{0,-9} | {1} | {3}", (apiResponseLocalVar.DownloadedAt - apiResponseLocalVar.RequestedAt).TotalSeconds, apiResponseLocalVar.StatusCode, apiResponseLocalVar.Path); }
171170

172171
/// <summary>
173172
/// Processes the server response
@@ -268,11 +267,17 @@ public async Task<IHelloWorldPostApiResponse> HelloWorldPostAsync(Option<HelloWo
268267

269268
using (HttpResponseMessage httpResponseMessageLocalVar = await HttpClient.SendAsync(httpRequestMessageLocalVar, cancellationToken).ConfigureAwait(false))
270269
{
271-
string responseContentLocalVar = await httpResponseMessageLocalVar.Content.ReadAsStringAsync(cancellationToken).ConfigureAwait(false);
272-
273270
ILogger<HelloWorldPostApiResponse> apiResponseLoggerLocalVar = LoggerFactory.CreateLogger<HelloWorldPostApiResponse>();
271+
HelloWorldPostApiResponse apiResponseLocalVar;
272+
273+
switch ((int)httpResponseMessageLocalVar.StatusCode) {
274+
default: {
275+
string responseContentLocalVar = await httpResponseMessageLocalVar.Content.ReadAsStringAsync(cancellationToken).ConfigureAwait(false);
276+
apiResponseLocalVar = new(apiResponseLoggerLocalVar, httpRequestMessageLocalVar, httpResponseMessageLocalVar, responseContentLocalVar, "/helloWorld", requestedAtLocalVar, _jsonSerializerOptions);
274277

275-
HelloWorldPostApiResponse apiResponseLocalVar = new(apiResponseLoggerLocalVar, httpRequestMessageLocalVar, httpResponseMessageLocalVar, responseContentLocalVar, "/helloWorld", requestedAtLocalVar, _jsonSerializerOptions);
278+
break;
279+
}
280+
}
276281

277282
AfterHelloWorldPostDefaultImplementation(apiResponseLocalVar, helloWorldPostRequest);
278283

@@ -316,6 +321,22 @@ public HelloWorldPostApiResponse(ILogger<HelloWorldPostApiResponse> logger, Syst
316321
OnCreated(httpRequestMessage, httpResponseMessage);
317322
}
318323

324+
/// <summary>
325+
/// The <see cref="HelloWorldPostApiResponse"/>
326+
/// </summary>
327+
/// <param name="logger"></param>
328+
/// <param name="httpRequestMessage"></param>
329+
/// <param name="httpResponseMessage"></param>
330+
/// <param name="contentStream"></param>
331+
/// <param name="path"></param>
332+
/// <param name="requestedAt"></param>
333+
/// <param name="jsonSerializerOptions"></param>
334+
public HelloWorldPostApiResponse(ILogger<HelloWorldPostApiResponse> logger, System.Net.Http.HttpRequestMessage httpRequestMessage, System.Net.Http.HttpResponseMessage httpResponseMessage, System.IO.Stream contentStream, string path, DateTime requestedAt, System.Text.Json.JsonSerializerOptions jsonSerializerOptions) : base(httpRequestMessage, httpResponseMessage, contentStream, path, requestedAt, jsonSerializerOptions)
335+
{
336+
Logger = logger;
337+
OnCreated(httpRequestMessage, httpResponseMessage);
338+
}
339+
319340
partial void OnCreated(global::System.Net.Http.HttpRequestMessage httpRequestMessage, System.Net.Http.HttpResponseMessage httpResponseMessage);
320341

321342
/// <summary>

samples/client/petstore/csharp/generichost/latest/HelloWorld/src/Org.OpenAPITools/Client/ApiResponse`1.cs

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,11 @@ public partial interface IApiResponse
3636
/// The raw content of this response.
3737
/// </summary>
3838
string RawContent { get; }
39+
40+
/// <summary>
41+
/// The raw binary stream (only set for binary responses)
42+
/// </summary>
43+
System.IO.Stream? ContentStream { get; }
3944

4045
/// <summary>
4146
/// The DateTime when the request was retrieved.
@@ -84,6 +89,11 @@ public partial class ApiResponse : IApiResponse
8489
/// </summary>
8590
public string RawContent { get; protected set; }
8691

92+
/// <summary>
93+
/// The raw binary stream (only set for binary responses)
94+
/// </summary>
95+
public System.IO.Stream? ContentStream { get; protected set; }
96+
8797
/// <summary>
8898
/// The IsSuccessStatusCode from the api response
8999
/// </summary>
@@ -147,6 +157,30 @@ public ApiResponse(global::System.Net.Http.HttpRequestMessage httpRequestMessage
147157
OnCreated(httpRequestMessage, httpResponseMessage);
148158
}
149159

160+
/// <summary>
161+
/// Construct the response using an HttpResponseMessage
162+
/// </summary>
163+
/// <param name="httpRequestMessage"></param>
164+
/// <param name="httpResponseMessage"></param>
165+
/// <param name="contentStream"></param>
166+
/// <param name="path"></param>
167+
/// <param name="requestedAt"></param>
168+
/// <param name="jsonSerializerOptions"></param>
169+
public ApiResponse(global::System.Net.Http.HttpRequestMessage httpRequestMessage, System.Net.Http.HttpResponseMessage httpResponseMessage, System.IO.Stream contentStream, string path, DateTime requestedAt, System.Text.Json.JsonSerializerOptions jsonSerializerOptions)
170+
{
171+
StatusCode = httpResponseMessage.StatusCode;
172+
Headers = httpResponseMessage.Headers;
173+
IsSuccessStatusCode = httpResponseMessage.IsSuccessStatusCode;
174+
ReasonPhrase = httpResponseMessage.ReasonPhrase;
175+
ContentStream = contentStream;
176+
RawContent = string.Empty;
177+
Path = path;
178+
RequestUri = httpRequestMessage.RequestUri;
179+
RequestedAt = requestedAt;
180+
_jsonSerializerOptions = jsonSerializerOptions;
181+
OnCreated(httpRequestMessage, httpResponseMessage);
182+
}
183+
150184
partial void OnCreated(global::System.Net.Http.HttpRequestMessage httpRequestMessage, System.Net.Http.HttpResponseMessage httpResponseMessage);
151185
}
152186
}

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

Lines changed: 26 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -149,8 +149,7 @@ private void AfterOneOfArrayDefaultImplementation(IOneOfArrayApiResponse apiResp
149149
bool suppressDefaultLog = false;
150150
AfterOneOfArray(ref suppressDefaultLog, apiResponseLocalVar, oneOfArrayRequest);
151151
if (!suppressDefaultLog)
152-
Logger.LogInformation("{0,-9} | {1} | {3}", (apiResponseLocalVar.DownloadedAt - apiResponseLocalVar.RequestedAt).TotalSeconds, apiResponseLocalVar.StatusCode, apiResponseLocalVar.Path);
153-
}
152+
Logger.LogInformation("{0,-9} | {1} | {3}", (apiResponseLocalVar.DownloadedAt - apiResponseLocalVar.RequestedAt).TotalSeconds, apiResponseLocalVar.StatusCode, apiResponseLocalVar.Path); }
154153

155154
/// <summary>
156155
/// Processes the server response
@@ -249,11 +248,17 @@ public async Task<IOneOfArrayApiResponse> OneOfArrayAsync(Option<OneOfArrayReque
249248

250249
using (HttpResponseMessage httpResponseMessageLocalVar = await HttpClient.SendAsync(httpRequestMessageLocalVar, cancellationToken).ConfigureAwait(false))
251250
{
252-
string responseContentLocalVar = await httpResponseMessageLocalVar.Content.ReadAsStringAsync(cancellationToken).ConfigureAwait(false);
253-
254251
ILogger<OneOfArrayApiResponse> apiResponseLoggerLocalVar = LoggerFactory.CreateLogger<OneOfArrayApiResponse>();
252+
OneOfArrayApiResponse apiResponseLocalVar;
253+
254+
switch ((int)httpResponseMessageLocalVar.StatusCode) {
255+
default: {
256+
string responseContentLocalVar = await httpResponseMessageLocalVar.Content.ReadAsStringAsync(cancellationToken).ConfigureAwait(false);
257+
apiResponseLocalVar = new(apiResponseLoggerLocalVar, httpRequestMessageLocalVar, httpResponseMessageLocalVar, responseContentLocalVar, "/one-of-array", requestedAtLocalVar, _jsonSerializerOptions);
255258

256-
OneOfArrayApiResponse apiResponseLocalVar = new(apiResponseLoggerLocalVar, httpRequestMessageLocalVar, httpResponseMessageLocalVar, responseContentLocalVar, "/one-of-array", requestedAtLocalVar, _jsonSerializerOptions);
259+
break;
260+
}
261+
}
257262

258263
AfterOneOfArrayDefaultImplementation(apiResponseLocalVar, oneOfArrayRequest);
259264

@@ -297,6 +302,22 @@ public OneOfArrayApiResponse(ILogger<OneOfArrayApiResponse> logger, System.Net.H
297302
OnCreated(httpRequestMessage, httpResponseMessage);
298303
}
299304

305+
/// <summary>
306+
/// The <see cref="OneOfArrayApiResponse"/>
307+
/// </summary>
308+
/// <param name="logger"></param>
309+
/// <param name="httpRequestMessage"></param>
310+
/// <param name="httpResponseMessage"></param>
311+
/// <param name="contentStream"></param>
312+
/// <param name="path"></param>
313+
/// <param name="requestedAt"></param>
314+
/// <param name="jsonSerializerOptions"></param>
315+
public OneOfArrayApiResponse(ILogger<OneOfArrayApiResponse> logger, System.Net.Http.HttpRequestMessage httpRequestMessage, System.Net.Http.HttpResponseMessage httpResponseMessage, System.IO.Stream contentStream, string path, DateTime requestedAt, System.Text.Json.JsonSerializerOptions jsonSerializerOptions) : base(httpRequestMessage, httpResponseMessage, contentStream, path, requestedAt, jsonSerializerOptions)
316+
{
317+
Logger = logger;
318+
OnCreated(httpRequestMessage, httpResponseMessage);
319+
}
320+
300321
partial void OnCreated(global::System.Net.Http.HttpRequestMessage httpRequestMessage, System.Net.Http.HttpResponseMessage httpResponseMessage);
301322

302323
/// <summary>

0 commit comments

Comments
 (0)