Description
Background and motivation
I apply DataAnnotations attributes (migrating from Newtonsoft.Json.Schema) to the JSON generated schema through JsonSchemaExporterOptions.TransformSchemaNode
. However, the built-in generator transforms part of the schema into a $ref
before I can apply my own transformations, resulting in an incorrect schema because the values of the attributes are not the same. Here's an example:
[TypeArgumentRegularExpression("[A-Za-z]+", 0)]
[TypeArgumentRegularExpression("[0-9]+", 1)]
public Dictionary<string, string[]>? Dict { get; set; }
[TypeArgumentRegularExpression("[A-Z]+", 0)]
[TypeArgumentRegularExpression("[a-z]+", 1)]
[TypeArgumentRegularExpression("[0-9]+", 2)]
public Dictionary<string, Dictionary<string, string[]>>? Dict2 { get; set; }
Note that TypeArgumentRegularExpression
is a custom attribute based on System.ComponentModel.DataAnnotations.RegularExpressionAttribute
which allows me to specify to which TKey/TValue the regex pattern should be applied. The resulting schema looks like:
"properties": {
"Dict": {
"type": "object",
"additionalProperties": false,
"patternProperties": {
"[A-Za-z]\u002B": {
"type": "array",
"items": {
"type": "string",
"pattern": "[0-9]\u002B"
}
}
}
},
"Dict2": {
"type": "object",
"additionalProperties": false,
"patternProperties": {
"[A-Z]\u002B": {
"$ref": "#/properties/Dict"
}
}
}
}
As you can see, the TValue of the second dictionary has been turned into a $ref to the first dictionary, even though it has a different regex pattern for TKey (Dict's TKey is [A-Za-z]+
, but Dict2-TValue's TKey only allows [a-z]+
).
I think the easiest solution for this would be an option to disable generating $refs.
API Proposal
namespace System.Text.Json.Schema;
public sealed class JsonSchemaExporterOptions
{
public bool GenerateRefs { get; init; }
}
API Usage
var transformer = new MyJsonSchemaTransformer();
var jsonSchemaExporterOptions = new JsonSchemaExporterOptions
{
TreatNullObliviousAsNonNullable = true,
TransformSchemaNode = transformer.TransformSchemaNode,
GenerateRefs = false,
};
var result = jsonSerializerOptions.GetJsonSchemaAsNode(typeof(MyObject), jsonSchemaExporterOptions).ToString();
Alternative Designs
No response
Risks
No response