-
-
Notifications
You must be signed in to change notification settings - Fork 1.3k
Description
Describe the bug
I was actually happy to see #3793 as this was a minor gap for us in the .NET 10 upgrade where we had some examples that were explicitly/intentionally written to the API Spec as null.
However moving to the new package 10.1.4 seems to exhibit strange behavior. I am only allowed to write a null example to the document if the data type is JsonSchemaType.String but not JsonSchemaTypeString | JsonSchemaType.Null.
Swashbuckle.AspNetCore/src/Swashbuckle.AspNetCore.SwaggerGen/XmlComments/XmlCommentsExampleHelper.cs
Lines 16 to 23 in 8ad6682
| var isStringType = type is { } value && | |
| value.HasFlag(JsonSchemaType.String) && | |
| !value.HasFlag(JsonSchemaType.Null); | |
| if (isStringType) | |
| { | |
| return string.Equals(exampleString, "null") ? JsonNullSentinel.JsonNull : JsonValue.Create(exampleString); | |
| } |
This seems inverted! I can set example=null on a non-nullable string, but not on a nullable string?
It also seems a bit funny that it's limited to strings and not any nullable type
Expected behavior
At the very least I would expect to be able to set the example value to null if the property itself supports being null i.e. with JsonSchemaType.Null | JsonSchemaType.String
Though I probably would not limit this to just strings at all! Perhaps something like this could suffice for any type of property:
var type = schema?.ResolveType(schemaRepository);
if (type is { } value && value.HasFlag(JsonSchemaType.Null) && string.Equals(exampleString, "null"))
{
return JsonNullSentinel.JsonNull;
}
// rest of methodActual behavior
Cannot write "example": null to document if schema resolves to JsonSchemaTypeString | JsonSchemaType.Null
Cannot write "example": null for numeric or other properties that have the JsonSchemaType.Null flag
Steps to reproduce
Consider this data type:
public sealed class MyType
{
/// <example>null</example>
[Required]
public string Ex0 { get; set; } = null!;
/// <example>null</example>
public string? Ex1 { get; set; }
/// <example>null</example>
public Guid Ex2 { get; set; }
/// <example>null</example>
public Guid? Ex3 { get; set; }
/// <example>null</example>
public int Ex4 { get; set; }
/// <example>null</example>
public int? Ex5 { get; set; }
/// <example>3</example>
public int? Ex6 { get; set; }
}The API Specification generated will produce
| Field | Expected Example | Actual Example | Correct |
|---|---|---|---|
Ex0 |
omitted | "example": null |
❌ |
Ex1 |
"example": null |
omitted | ❌ |
Ex2 |
omitted | "example": null |
❌ |
Ex3 |
"example": null |
omitted | ❌ |
Ex4 |
omitted | omitted | ✅ |
Ex5 |
"example": null |
omitted | ❌ |
Ex6 |
"example": 3 |
"example": 3 |
✅ |
Exception(s) (if any)
No response
Swashbuckle.AspNetCore version
10.1.4
.NET Version
10
Anything else?
As a work-around, you can write the literal value of JsonNullSentinel.NullValue as your example and it will get converted just fine:
public sealed class MyType
{
/// <example>openapi-json-null-sentinel-value-2BF93600-0FE4-4250-987A-E5DDB203E464</example>
public string? Ex1 { get; set; }
}However that is a bit heavy handed and likely an implementation detail!