Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// This logic may be modified with the AsModel.mustache template
// NOTICE: Consider this AsModel template deprecated. Implement the appropriate partial method instead
return Is{{vendorExtensions.x-http-status}}
? {{#isBinary}}ContentStream{{/isBinary}}{{^isBinary}}System.Text.Json.JsonSerializer.Deserialize<{{#isModel}}{{^containerType}}{{packageName}}.{{modelPackage}}.{{/containerType}}{{/isModel}}{{{dataType}}}>(RawContent, _jsonSerializerOptions){{/isBinary}}
: {{#net60OrLater}}null{{/net60OrLater}}{{^net60OrLater}}default{{/net60OrLater}};
Original file line number Diff line number Diff line change
Expand Up @@ -896,6 +896,16 @@ namespace {{packageName}}.{{apiPackage}}
/// </summary>
/// <returns></returns>
public {{#isModel}}{{^containerType}}{{packageName}}.{{modelPackage}}.{{/containerType}}{{/isModel}}{{{dataType}}}{{#nrt}}?{{/nrt}}{{^nrt}}{{#vendorExtensions.x-is-value-type}}?{{/vendorExtensions.x-is-value-type}}{{/nrt}} {{vendorExtensions.x-http-status}}()
{
bool suppressDefault = false;
{{#isModel}}{{^containerType}}{{packageName}}.{{modelPackage}}.{{/containerType}}{{/isModel}}{{{dataType}}}{{#nrt}}?{{/nrt}}{{^nrt}}{{#vendorExtensions.x-is-value-type}}?{{/vendorExtensions.x-is-value-type}}{{/nrt}} result = {{#net60OrLater}}null{{/net60OrLater}}{{^net60OrLater}}default{{/net60OrLater}};
On{{vendorExtensions.x-http-status}}(ref suppressDefault, ref result);
if (!suppressDefault)
result = Default{{vendorExtensions.x-http-status}}();
return result;
}

private {{#isModel}}{{^containerType}}{{packageName}}.{{modelPackage}}.{{/containerType}}{{/isModel}}{{{dataType}}}{{#nrt}}?{{/nrt}}{{^nrt}}{{#vendorExtensions.x-is-value-type}}?{{/vendorExtensions.x-is-value-type}}{{/nrt}} Default{{vendorExtensions.x-http-status}}()
{
{{#lambda.trimTrailingWithNewLine}}
{{#lambda.indent4}}
Expand All @@ -904,6 +914,8 @@ namespace {{packageName}}.{{apiPackage}}
{{/lambda.trimTrailingWithNewLine}}
}

partial void On{{vendorExtensions.x-http-status}}(ref bool suppressDefault, ref {{#isModel}}{{^containerType}}{{packageName}}.{{modelPackage}}.{{/containerType}}{{/isModel}}{{{dataType}}}{{#nrt}}?{{/nrt}}{{^nrt}}{{#vendorExtensions.x-is-value-type}}?{{/vendorExtensions.x-is-value-type}}{{/nrt}} result);

/// <summary>
/// Returns true if the response is {{code}} {{vendorExtensions.x-http-status}} and the deserialized response is not null
/// </summary>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -337,12 +337,24 @@ public ListApiResponse(ILogger<DefaultApi> logger, System.Net.Http.HttpRequestMe
/// <returns></returns>
public string? Ok()
{
// This logic may be modified with the AsModel.mustache template
bool suppressDefault = false;
string? result = null;
OnOk(ref suppressDefault, ref result);
if (!suppressDefault)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2: The Ok() flow re-runs DefaultOk() after the OnOk hook whenever suppressDefault is false. If a hook follows the documented "set result = DefaultOk() first, then patch, while letting DefaultOk run" guidance, the response body is deserialized twice and the second DefaultOk() overwrites the patched result, silently discarding the customization. The guide should instruct hooks to set suppressDefault = true after calling DefaultOk(), or the hook should be the single deserialization point.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At samples/client/petstore/csharp/generichost/latest/AnnotatedEnum/src/Org.OpenAPITools/Api/DefaultApi.cs, line 343:

<comment>The Ok() flow re-runs DefaultOk() after the OnOk hook whenever suppressDefault is false. If a hook follows the documented "set result = DefaultOk() first, then patch, while letting DefaultOk run" guidance, the response body is deserialized twice and the second DefaultOk() overwrites the patched result, silently discarding the customization. The guide should instruct hooks to set suppressDefault = true after calling DefaultOk(), or the hook should be the single deserialization point.</comment>

<file context>
@@ -337,12 +337,24 @@ public ListApiResponse(ILogger<DefaultApi> logger, System.Net.Http.HttpRequestMe
+                bool suppressDefault = false;
+                string? result = null;
+                OnOk(ref suppressDefault, ref result);
+                if (!suppressDefault)
+                    result = DefaultOk();
+                return result;
</file context>

result = DefaultOk();
return result;
}

private string? DefaultOk()
{
// NOTICE: Consider this AsModel template deprecated. Implement the appropriate partial method instead
return IsOk
? System.Text.Json.JsonSerializer.Deserialize<string>(RawContent, _jsonSerializerOptions)
: null;
}

partial void OnOk(ref bool suppressDefault, ref string? result);

/// <summary>
/// Returns true if the response is 200 Ok and the deserialized response is not null
/// </summary>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -344,12 +344,24 @@ public IconsApiResponse(ILogger<DefaultApi> logger, System.Net.Http.HttpRequestM
/// <returns></returns>
public Org.OpenAPITools.Model.IconsDefaultResponse? Default()
{
// This logic may be modified with the AsModel.mustache template
bool suppressDefault = false;
Org.OpenAPITools.Model.IconsDefaultResponse? result = null;
OnDefault(ref suppressDefault, ref result);
if (!suppressDefault)
result = DefaultDefault();
return result;
}

private Org.OpenAPITools.Model.IconsDefaultResponse? DefaultDefault()
{
// NOTICE: Consider this AsModel template deprecated. Implement the appropriate partial method instead
return IsDefault
? System.Text.Json.JsonSerializer.Deserialize<Org.OpenAPITools.Model.IconsDefaultResponse>(RawContent, _jsonSerializerOptions)
: null;
}

partial void OnDefault(ref bool suppressDefault, ref Org.OpenAPITools.Model.IconsDefaultResponse? result);

/// <summary>
/// Returns true if the response is 0 Default and the deserialized response is not null
/// </summary>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -331,12 +331,24 @@ public GetWidgetApiResponse(ILogger<DefaultApi> logger, System.Net.Http.HttpRequ
/// <returns></returns>
public Org.OpenAPITools.Model.Widget? Ok()
{
// This logic may be modified with the AsModel.mustache template
bool suppressDefault = false;
Org.OpenAPITools.Model.Widget? result = null;
OnOk(ref suppressDefault, ref result);
if (!suppressDefault)
result = DefaultOk();

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2: The hook silently discards a caller's patched result unless they also set suppressDefault = true, which makes the documented "patch while letting DefaultOk run" path lose its patch and deserialize twice. Consider only falling back to the default when the hook left result null (e.g. if (!suppressDefault && result is null) result = DefaultOk();) so a patched value is preserved, and be aware the current overload contract requires the suppress flag even for patching.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At samples/client/petstore/csharp/generichost/latest/NullTypes/src/Org.OpenAPITools/Api/DefaultApi.cs, line 338:

<comment>The hook silently discards a caller's patched `result` unless they also set `suppressDefault = true`, which makes the documented "patch while letting DefaultOk run" path lose its patch and deserialize twice. Consider only falling back to the default when the hook left `result` null (e.g. `if (!suppressDefault && result is null) result = DefaultOk();`) so a patched value is preserved, and be aware the current overload contract requires the suppress flag even for patching.</comment>

<file context>
@@ -331,12 +331,24 @@ public GetWidgetApiResponse(ILogger<DefaultApi> logger, System.Net.Http.HttpRequ
+                Org.OpenAPITools.Model.Widget? result = null;
+                OnOk(ref suppressDefault, ref result);
+                if (!suppressDefault)
+                    result = DefaultOk();
+                return result;
+            }
</file context>

return result;
}

private Org.OpenAPITools.Model.Widget? DefaultOk()
{
// NOTICE: Consider this AsModel template deprecated. Implement the appropriate partial method instead
return IsOk
? System.Text.Json.JsonSerializer.Deserialize<Org.OpenAPITools.Model.Widget>(RawContent, _jsonSerializerOptions)
: null;
}

partial void OnOk(ref bool suppressDefault, ref Org.OpenAPITools.Model.Widget? result);
Comment thread
devhl-labs marked this conversation as resolved.

/// <summary>
/// Returns true if the response is 200 Ok and the deserialized response is not null
/// </summary>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -385,12 +385,24 @@ public Call123TestSpecialTagsApiResponse(ILogger<AnotherFakeApi> logger, System.
/// <returns></returns>
public Org.OpenAPITools.Model.ModelClient? Ok()
{
// This logic may be modified with the AsModel.mustache template
bool suppressDefault = false;
Org.OpenAPITools.Model.ModelClient? result = null;
OnOk(ref suppressDefault, ref result);
if (!suppressDefault)
result = DefaultOk();
return result;
}

private Org.OpenAPITools.Model.ModelClient? DefaultOk()
{
// NOTICE: Consider this AsModel template deprecated. Implement the appropriate partial method instead
return IsOk
? System.Text.Json.JsonSerializer.Deserialize<Org.OpenAPITools.Model.ModelClient>(RawContent, _jsonSerializerOptions)
: null;
}

partial void OnOk(ref bool suppressDefault, ref Org.OpenAPITools.Model.ModelClient? result);

/// <summary>
/// Returns true if the response is 200 Ok and the deserialized response is not null
/// </summary>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -620,12 +620,24 @@ public FooGetApiResponse(ILogger<DefaultApi> logger, System.Net.Http.HttpRequest
/// <returns></returns>
public Org.OpenAPITools.Model.FooGetDefaultResponse? Default()
{
// This logic may be modified with the AsModel.mustache template
bool suppressDefault = false;
Org.OpenAPITools.Model.FooGetDefaultResponse? result = null;
OnDefault(ref suppressDefault, ref result);
if (!suppressDefault)
result = DefaultDefault();
return result;
}

private Org.OpenAPITools.Model.FooGetDefaultResponse? DefaultDefault()
{
// NOTICE: Consider this AsModel template deprecated. Implement the appropriate partial method instead
return IsDefault
? System.Text.Json.JsonSerializer.Deserialize<Org.OpenAPITools.Model.FooGetDefaultResponse>(RawContent, _jsonSerializerOptions)
: null;
}

partial void OnDefault(ref bool suppressDefault, ref Org.OpenAPITools.Model.FooGetDefaultResponse? result);

/// <summary>
/// Returns true if the response is 0 Default and the deserialized response is not null
/// </summary>
Expand Down Expand Up @@ -1047,12 +1059,24 @@ public HelloApiResponse(ILogger<DefaultApi> logger, System.Net.Http.HttpRequestM
/// <returns></returns>
public List<Guid>? Ok()
{
// This logic may be modified with the AsModel.mustache template
bool suppressDefault = false;
List<Guid>? result = null;
OnOk(ref suppressDefault, ref result);
if (!suppressDefault)
result = DefaultOk();
return result;
}

private List<Guid>? DefaultOk()
{
// NOTICE: Consider this AsModel template deprecated. Implement the appropriate partial method instead
return IsOk
? System.Text.Json.JsonSerializer.Deserialize<List<Guid>>(RawContent, _jsonSerializerOptions)
: null;
}

partial void OnOk(ref bool suppressDefault, ref List<Guid>? result);

/// <summary>
/// Returns true if the response is 200 Ok and the deserialized response is not null
/// </summary>
Expand Down Expand Up @@ -1270,12 +1294,24 @@ public RedirectOrDefaultApiResponse(ILogger<DefaultApi> logger, System.Net.Http.
/// <returns></returns>
public string? Default()
{
// This logic may be modified with the AsModel.mustache template
bool suppressDefault = false;
string? result = null;
OnDefault(ref suppressDefault, ref result);
if (!suppressDefault)
result = DefaultDefault();
return result;
}

private string? DefaultDefault()
{
// NOTICE: Consider this AsModel template deprecated. Implement the appropriate partial method instead
return IsDefault
? System.Text.Json.JsonSerializer.Deserialize<string>(RawContent, _jsonSerializerOptions)
: null;
}

partial void OnDefault(ref bool suppressDefault, ref string? result);

/// <summary>
/// Returns true if the response is 0 Default and the deserialized response is not null
/// </summary>
Expand Down Expand Up @@ -1487,12 +1523,24 @@ public RolesReportGetApiResponse(ILogger<DefaultApi> logger, System.Net.Http.Htt
/// <returns></returns>
public List<List<RolesReportsHash>>? Ok()
{
// This logic may be modified with the AsModel.mustache template
bool suppressDefault = false;
List<List<RolesReportsHash>>? result = null;
OnOk(ref suppressDefault, ref result);
if (!suppressDefault)
result = DefaultOk();
return result;
}

private List<List<RolesReportsHash>>? DefaultOk()
{
// NOTICE: Consider this AsModel template deprecated. Implement the appropriate partial method instead
return IsOk
? System.Text.Json.JsonSerializer.Deserialize<List<List<RolesReportsHash>>>(RawContent, _jsonSerializerOptions)
: null;
}

partial void OnOk(ref bool suppressDefault, ref List<List<RolesReportsHash>>? result);

/// <summary>
/// Returns true if the response is 200 Ok and the deserialized response is not null
/// </summary>
Expand Down Expand Up @@ -1704,12 +1752,24 @@ public TestApiResponse(ILogger<DefaultApi> logger, System.Net.Http.HttpRequestMe
/// <returns></returns>
public Org.OpenAPITools.Model.NotificationtestGetElementsV1ResponseMPayload? Ok()
{
// This logic may be modified with the AsModel.mustache template
bool suppressDefault = false;
Org.OpenAPITools.Model.NotificationtestGetElementsV1ResponseMPayload? result = null;
OnOk(ref suppressDefault, ref result);
if (!suppressDefault)
result = DefaultOk();
return result;
}

private Org.OpenAPITools.Model.NotificationtestGetElementsV1ResponseMPayload? DefaultOk()
{
// NOTICE: Consider this AsModel template deprecated. Implement the appropriate partial method instead
return IsOk
? System.Text.Json.JsonSerializer.Deserialize<Org.OpenAPITools.Model.NotificationtestGetElementsV1ResponseMPayload>(RawContent, _jsonSerializerOptions)
: null;
}

partial void OnOk(ref bool suppressDefault, ref Org.OpenAPITools.Model.NotificationtestGetElementsV1ResponseMPayload? result);

/// <summary>
/// Returns true if the response is 200 Ok and the deserialized response is not null
/// </summary>
Expand Down
Loading
Loading