You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: _docs/schema/basics.md
+28-1Lines changed: 28 additions & 1 deletion
Original file line number
Diff line number
Diff line change
@@ -45,7 +45,7 @@ JSON Schema is expressed as a collection of keywords, each of which provides a s
45
45
46
46
There are two options when building a schema: defining it inline using the fluent builder and defining it externally and deserializing. Which method you use depends on your specific requirements.
47
47
48
-
## Deserialization {#schema-deserialization}
48
+
## Serialization and Deserialization {#schema-deserialization}
49
49
50
50
*JsonSchema.Net* schemas are fully serializable.
51
51
@@ -61,6 +61,33 @@ var mySchema = JsonSerializer.Deserialize<JsonSchema>(content);
61
61
62
62
Done.
63
63
64
+
### Ahead of Time (AOT) compatibility {#aot}
65
+
66
+
_JsonSchema.Net_ v6 includes updates to support [Native AOT applications](https://learn.microsoft.com/en-us/dotnet/core/deploying/native-aot/). In order to take advantage of this, there are a few things you'll need to do.
67
+
68
+
First, on your `JsonSerializerContext`, add the following attributes:
69
+
70
+
```c#
71
+
[JsonSerializable(typeof(JsonSchema))]
72
+
[JsonSerializable(typeof(EvaluationResults))]
73
+
```
74
+
75
+
It's recommended that you create a single `JsonSerializerOptions` object (or a few if you need different configurations) and reuse it rather than creating them ad-hoc. When you create one, you'll need to configure its `TypeResolverChain` with your serializer context:
If you don't have any custom keywords, you're done. Congratulations.
85
+
86
+
If you do have custom keywords, please see the AOT section on the [Vocabularies docs](/schema/vocabs#aot).
87
+
88
+
> The vocabulary library extensions for _JsonSchema.Net_ are also AOT-compatible and require no further setup.
89
+
{: .prompt-tip}
90
+
64
91
## Inline {#schema-inlining}
65
92
66
93
There are many reasons why you would want to hard-code your schemas. This library actually hard-codes all of the meta-schemas. Whatever your reason, the `JsonSchemaBuilder` class is going to be your friend.
Copy file name to clipboardExpand all lines: _docs/schema/schemagen/schema-generation.md
+3Lines changed: 3 additions & 0 deletions
Original file line number
Diff line number
Diff line change
@@ -16,6 +16,9 @@ var schema = schemaBuilder.FromType<MyType>().Build();
16
16
17
17
Done.
18
18
19
+
> The validating converter described in this document requires AOT-incompatible reflection to operate, so it will not be usable in a Native AOT context.
20
+
{: .prompt-warning}
21
+
19
22
## IMPORTANT {#schema-schemagen-disclaimer}
20
23
21
24
Ideally, this functionality should be used to create a starting point in authoring a schema. The schemas output by this library should be reviewed by actual people prior to being put into a production system.
Copy file name to clipboardExpand all lines: _docs/schema/serialization.md
+4-1Lines changed: 4 additions & 1 deletion
Original file line number
Diff line number
Diff line change
@@ -1,7 +1,7 @@
1
1
---
2
2
layout: page
3
3
title: Enhancing Deserialization with JSON Schema
4
-
bookmark: Serialization
4
+
bookmark: Serialization with Validation
5
5
permalink: /schema/:title/
6
6
icon: fas fa-tag
7
7
order: "01.2"
@@ -15,6 +15,9 @@ Let's walk through it.
15
15
> More on JSON Schema support during deserialization can be found on the `json-everything`[blog](https://blog.json-everything.net/posts/deserialization-with-schemas/).
16
16
{: .prompt-tip }
17
17
18
+
> The validating converter described in this document requires AOT-incompatible reflection to operate, so it will not be usable in a Native AOT context.
19
+
{: .prompt-warning}
20
+
18
21
## Setting up the converter {#schema-deserialization-setup}
19
22
20
23
Custom JSON converters are added via the `JsonSerializationOptions.Converters` property. Any converters in this collection will have priority over the default set of converters that ship with .Net. You can read more about custom converters in their [documentation](https://learn.microsoft.com/en-us/dotnet/standard/serialization/system-text-json/converters-how-to?pivots=dotnet-7-0).
Copy file name to clipboardExpand all lines: _docs/schema/vocabs.md
+26-12Lines changed: 26 additions & 12 deletions
Original file line number
Diff line number
Diff line change
@@ -104,7 +104,7 @@ The keywords must still be registered separately (see "Defining Custom Keywords"
104
104
105
105
It's not always necessary to have a meta-schema for your vocabulary. However, if you want to enable `EvaluationOptions.ValidateMetaschema`, you will need to register it.
`JsonSchema` has been designed to allow you to create your own keywords. There are several steps that need to be performed to do this.
110
110
@@ -122,17 +122,31 @@ And your new keyword is ready to use.
122
122
123
123
Lastly, remember that the best resource building keywords is [the code](https://github.com/gregsdennis/json-everything/tree/master/JsonSchema) where all of the built-in keywords are defined.
124
124
125
-
## Evaluation philosophy
125
+
###Evaluation philosophy
126
126
127
127
Starting with version 5 of _JsonSchema.Net_, schema evaluation occurs in two stages: gathering constraints and processing evaluations. Constraints represent all of the work that can be performed by the keyword without an instance, while evaluations complete the work. By separating these stages, _JsonSchema.Net_ can reuse the constraints for subsequent runs, allowing faster run times and fewer memory allocations.
128
128
129
129
Both stages are defined by implementing the single method on `IJsonSchemaKeyword`.
_JsonSchema.Net_ v6 includes updates to support [Native AOT applications](https://learn.microsoft.com/en-us/dotnet/core/deploying/native-aot/). Please be sure to read the main AOT section on the [overview page](/schema/basics#aot).
134
+
135
+
Frist, you'll need to add `[JsonSerializable]` attributes for any custom keywords.
136
+
137
+
```c#
138
+
[JsonSerializable(typeof(MyKeyword))]
139
+
```
140
+
141
+
Second, you'll need to register your keywords using the `SchemaKeywordRegistry.Register<T>(JsonSerializerContext)` method overload, passing in your serializer context, to provide the library access to the `JsonTypeInfo` for your keyword type.
142
+
143
+
Lastly, due to the dynamic nature of how rules are serialized, your JSON converter MUST implement `IWeaklyTypedJsonConverter` which is defined by _Json.More.Net_. The library also defines a `WeaklyTypeJsonConverter<T>` abstract class that you can use as a base. It's also highly recommended that you take advantage of the `JsonSerializerOptions`[read/write extensions](/more/json-more/#ahead-of-time-aot-compilation-support) provided by _Json.More.Net_.
Implementing your keyword will require some initial thought and design around what work the keyword can perform without the instance and what work requires the instance. To illustrate this, let's look at a couple of the existing keyword implementations.
134
148
135
-
### `maximum`
149
+
####`maximum`
136
150
137
151
The `maximum` keyword is basically all instance. It asks, "Is the instance a number, and, if so, does it exceed some maximum value?" As such, there's not really much in the way of pre-processing that can be accomplished here that isn't handled in the background. Therefore, all of the work is done by an `Evaluator()` method.
138
152
@@ -174,7 +188,7 @@ For `maximum`, evaluation means we check if the value is a number. If not, we i
174
188
> `maximum` doesn't have any nested results, but it's still good form to explicitly indicate this.
175
189
{: .prompt-info }
176
190
177
-
### `properties`
191
+
####`properties`
178
192
179
193
The `properties` keyword presents an opportunity to calculate some things before we have the instance. For example, with this schema
180
194
@@ -233,7 +247,7 @@ When we move into the evaluation phase, all of the child constraints that align
233
247
> The specification requires that annotations are not reported when validation fails, however this requirement is enforced at the (sub)schema level, not at the keyword level. Annotations are still generally required for sibling keywords (i.e. within the same subschema) to interoperate correctly.
234
248
{: .prompt-warning }
235
249
236
-
### Other variations
250
+
####Other variations
237
251
238
252
There are a few other variations of keyword interactions, and it may be worth inspecting the code for some of these examples.
239
253
@@ -254,7 +268,7 @@ There are a few other variations of keyword interactions, and it may be worth in
254
268
255
269
Understanding the patterns that already exist will help you build your own keyword implementations.
256
270
257
-
### Saving evaluation results
271
+
####Saving evaluation results
258
272
259
273
Once you have validated the instance, you'll need to record the results. These methods are available on the local result object.
260
274
@@ -267,7 +281,7 @@ Once you have validated the instance, you'll need to record the results. These
267
281
268
282
Set any annotations by using `.SetAnnotation()` on the local result object. Generally this needs to be done whether the keyword passes or fails validation. Annotations are stored as a key-value pair, using the keyword name as the key. The value can be anything, but it _should_ be JSON-serializable in order to be rendered properly in the output.
269
283
270
-
## 2. Implement one of the schema-container interfaces {#schema-vocabs-custom-keywords-2}
284
+
###2. Implement one of the schema-container interfaces {#schema-vocabs-custom-keywords-2}
271
285
272
286
If your keyword contains one or more subschemas, you'll need to implement one of these:
273
287
@@ -278,7 +292,7 @@ If your keyword contains one or more subschemas, you'll need to implement one of
278
292
279
293
These will be used at the beginning of the first evaluation and during schema registration to traverse all of the subschemas a provide IDs where none is explicitly declared. This goes on to help `$ref` and friends to their job while also making that job faster.
280
294
281
-
## 3. Apply some attributes {#schema-vocabs-custom-keyword-3}
295
+
###3. Apply some attributes {#schema-vocabs-custom-keyword-3}
282
296
283
297
*JsonSchema.Net* contains several attributes that you should use to specify some metadata about your keyword.
284
298
@@ -287,11 +301,11 @@ These will be used at the beginning of the first evaluation and during schema re
287
301
-`SchemaVersion` - Declares a version that supports the keyword. This can be used multiple times to declare additional drafts.
288
302
-`Vocabulary` - Declares the ID of the vocabulary which defines the the keyword.
289
303
290
-
## 4. Register your keyword {#schema-vocabs-custom-keywords-4}
304
+
###4. Register your keyword {#schema-vocabs-custom-keywords-4}
291
305
292
306
To make *JsonSchema.Net* aware of your keyword, you must register it with `SchemaKeywordRegistry.Register<T>()`. This will enable deserialization.
293
307
294
-
### Now make it nice to use {#schema-vocabs-custom-extensions}
308
+
####Now make it nice to use {#schema-vocabs-custom-extensions}
295
309
296
310
To enable the fluent construction interface for your keyword, simply create an extension method on `JsonSchemaBuilder` that adds the keyword and returns the builder. For example, adding a `description` keyword is implemented by this method:
0 commit comments