Skip to content
Merged
Changes from 11 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
103 changes: 103 additions & 0 deletions aspnetcore/fundamentals/openapi/include-metadata.md
Original file line number Diff line number Diff line change
Expand Up @@ -493,6 +493,8 @@ of the property in the schema.

### type and format

:::moniker range="< aspnetcore-10.0"

The JSON Schema library maps standard C# types to OpenAPI `type` and `format` as follows:

| C# Type | OpenAPI `type` | OpenAPI `format` |
Expand Down Expand Up @@ -520,6 +522,84 @@ Note that object and dynamic types have _no_ type defined in the OpenAPI because

The `type` and `format` can also be set with a [Schema Transformer](xref:fundamentals/openapi/customize-openapi#use-schema-transformers). For example, you may want the `format` of decimal types to be `decimal` instead of `double`.

:::moniker-end

:::moniker range=">= aspnetcore-10.0"

#### Numeric types

The JSON Schema library maps standard C# numeric types to OpenAPI `type` and `format` based on the
<xref:System.Text.Json.JsonSerializerOptions.NumberHandling> property of the <xref:System.Text.Json.JsonSerializerOptions>
used in the app. In ASP.NET Core Web API apps, the default value of this property is `JsonNumberHandling.AllowReadingFromString`.

When the <xref:System.Text.Json.JsonSerializerOptions.NumberHandling> property is set to `JsonNumberHandling.AllowReadingFromString`, the numeric types are mapped as follows:

| C# Type | OpenAPI `type` | OpenAPI `format` | Other assertions |
| -------------- | ---------------- | ---------------- | ------------------------------ |
| int | [integer,string] | int32 | pattern `<digits>` |
| long | [integer,string] | int64 | pattern `<digits>` |
| short | [integer,string] | int16 | pattern `<digits>` |
| byte | [integer,string] | uint8 | pattern `<digits>` |
| float | [number,string] | float | pattern `<digits with decimal >` |
| double | [number,string] | double | pattern `<digits with decimal >` |
| decimal | [number,string] | double | pattern `<digits with decimal >` |




| C# Type | OpenAPI `type` | OpenAPI `format` | Other assertions |
| -------------- | ---------------- | ---------------- | ------------------------------ |
<!--
| int | [integer,string] | int32 | pattern `<digits>` | pattern: `"^-?(?:0|[1-9]\\d*)$"`
| long | [integer,string] | int64 | pattern `<digits>` |
| short | [integer,string] | int16 | pattern `<digits>` |
| byte | [integer,string] | uint8 | pattern `<digits>` |
| float | [number,string] | float | pattern `<digits with decimal >` | pattern: `"^-?(?:0|[1-9]\\d*)(?:\\.\\d+)?(?:[eE][+-]?\\d+)?$"`
| double | [number,string] | double | pattern `<digits with decimal >` |
| decimal | [number,string] | double | pattern `<digits with decimal >` | pattern: `"^-?(?:0|[1-9]\\d*)(?:\\.\\d+)?$"`
Comment on lines +548 to +554
Copy link
Contributor

@Rick-Anderson Rick-Anderson Apr 15, 2025

Choose a reason for hiding this comment

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

@mikekistler
Took me awhile to figure that build error. See the | in the pattern? Even commented out, the parser picks up the column separator before stripping comment - error
even with ``` back ticks, same column error. Very strange

image

The other build error took a bit too, you had :: moniker-end, only two :, and 3 required. I've never made that mistake - every, because I'm dyslexic and can't type. I copy/paste.

Copy link
Contributor

Choose a reason for hiding this comment

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

@tdykstra @guardrex strange you can't have comments after a row that include a pipe | - even in a comment, even code fenced

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Oh @Rick-Anderson ... so sorry! I think I force-pushed and erased some of your changes by accident. I should have been more careful. I will try to recover.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Okay ... I think I restored your version. I will be more careful from now on.

Copy link
Contributor

@Rick-Anderson Rick-Anderson Apr 16, 2025

Choose a reason for hiding this comment

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

Oh @Rick-Anderson ... so sorry! I think I force-pushed and erased some of your changes by accident. I should have been more careful. I will try to recover.

I should have made clear I pushed some commits, sorry. I thought you were finished.

-->

If the app is configured to produce OpenAPI 3.0 or OpenAPI v2 documents, where the `type` field cannot have an array value, the `type` field is dropped.

When the <xref:System.Text.Json.JsonSerializerOptions.NumberHandling> property is set to `JsonNumberHandling.Strict`, the numeric types are mapped as follows:

| C# Type | OpenAPI `type` | OpenAPI `format` |
| -------------- | -------------- | ---------------- |
| int | integer | int32 |
| long | integer | int64 |
| short | integer | int16 |
| byte | integer | uint8 |
| float | number | float |
| double | number | double |
| decimal | number | double |

#### String types

The following table shows how C# types map to `string` type properties in the generated OpenAPI document:

| C# Type | OpenAPI `type` | OpenAPI `format` | Other assertions |
| -------------- | -------------- | ---------------- | ------------------------------ |
| string | string | | |
| char | string | char | minLength: 1, maxLength: 1 |
| byte[] | string | byte | |
| DateTimeOffset | string | date-time | |
| DateOnly | string | date | |
| TimeOnly | string | time | |
| Uri | string | uri | |
| Guid | string | uuid | |

#### Other types

Other C# types are represented in the generated OpenAPI document as shown in the following table:

| C# Type | OpenAPI `type` | OpenAPI `format` |
| -------------- | -------------- | ---------------- |
| bool | boolean | |
| object | _omitted_ | |
| dynamic | _omitted_ | |

:::moniker-end

### Use attributes to add metadata

ASP.NET uses metadata from attributes on class or record properties to set metadata on the corresponding properties of the generated schema.
Expand Down Expand Up @@ -600,8 +680,31 @@ An enum type without a [`[JsonConverter]`](xref:System.Text.Json.Serialization.

#### nullable

:::moniker range="< aspnetcore-10.0"

Properties defined as a nullable value or reference type have `nullable: true` in the generated schema. This is consistent with the default behavior of the <xref:System.Text.Json> deserializer, which accepts `null` as a valid value for a nullable property.

:::moniker-end
:::moniker range=">= aspnetcore-10.0"

Properties defined as a nullable value or reference type appear in the generated schema with a `type` keyword whose value is an array that includes `null` as one of the types. This is consistent with the default behavior of the <xref:System.Text.Json> deserializer, which accepts `null` as a valid value for a nullable property.

For example, a C# property defined as `string?` is represented in the generated schema as:

```json
"nullableString": {
"description": "A property defined as string?",
"type": [
"null",
"string"
]
},
```

If the app is configured to produce OpenAPI v3.0 or OpenAPI v2 documents, nullable value or reference types have `nullable: true` in the generated schema because these OpenAPI versions do not allow the `type` field to be an array.

:::moniker-end

#### additionalProperties

Schemas are generated without an `additionalProperties` assertion by default, which implies the default of `true`. This is consistent with the default behavior of the <xref:System.Text.Json> deserializer, which silently ignores additional properties in a JSON object.
Expand Down