Skip to content

Commit e922284

Browse files
config JsonOptions globally /3 (#35280)
* config JsonOptions globally /3 * config JsonOptions globally /3 * config JsonOptions globally /3 * config JsonOptions globally /3 * config JsonOptions globally /3 * config JsonOptions globally /3 * config JsonOptions globally /3 * config JsonOptions globally /3 * config JsonOptions globally /3 * config JsonOptions globally /3 * config JsonOptions globally /3 * config JsonOptions globally /3
1 parent 79cd122 commit e922284

File tree

7 files changed

+257
-6
lines changed

7 files changed

+257
-6
lines changed

aspnetcore/fundamentals/openapi/include-metadata.md

Lines changed: 23 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ description: Learn how to add OpenAPI metadata in an ASP.NET Core app
55
ms.author: safia
66
monikerRange: '>= aspnetcore-9.0'
77
ms.custom: mvc
8-
ms.date: 10/26/2024
8+
ms.date: 4/22/2024
99
uid: fundamentals/openapi/include-metadata
1010
---
1111
# Include OpenAPI metadata in an ASP.NET Core app
@@ -619,19 +619,19 @@ public enum DayOfTheWeekAsString
619619
}
620620
```
621621

622-
A special case is when an enum type has the `[Flags]` attribute, which indicates that the enum can be treated as a bit field; that is, a set of flags. A flags enum with a `[JsonConverterAttribute]` is defined as `type: string` in the generated schema with no `enum` property, since the value could be any combination of the enum values. For example, the following enum:
622+
A special case is when an enum type has the `[Flags]` attribute, which indicates that the enum can be treated as a bit field; that is, a set of flags. A flags `enum` with a `[JsonConverterAttribute]` is defined as `type: string` in the generated schema with no `enum` property. No `enum` property is generated because the value could be any combination of the enum values. For example, the following `enum` could have values such as `"Pepperoni, Sausage"` or `"Sausage, Mushrooms, Anchovies"`:
623623

624624
```csharp
625625
[Flags, JsonConverter(typeof(JsonStringEnumConverter<PizzaToppings>))]
626626
public enum PizzaToppings { Pepperoni = 1, Sausage = 2, Mushrooms = 4, Anchovies = 8 }
627627
```
628628

629-
could have values such as `"Pepperoni, Sausage"` or `"Sausage, Mushrooms, Anchovies"`.
630-
631629
An enum type without a [`[JsonConverter]`](xref:System.Text.Json.Serialization.JsonConverterAttribute) will be defined as `type: integer` in the generated schema.
632630

633631
**Note:** The [`[AllowedValues]`](xref:System.ComponentModel.DataAnnotations.AllowedValuesAttribute) attribute does not set the `enum` values of a property.
634632

633+
[Set JSON options globally](#set-json-serialization-options-globally) shows how to set the the `JsonStringEnumConverter` globally.
634+
635635
#### nullable
636636

637637
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.
@@ -668,6 +668,25 @@ An abstract class with a [`[JsonPolymorphic]`](xref:System.Text.Json.Serializati
668668

669669
A schema transformer can be used to override any default metadata or add additional metadata, such as `example` values, to the generated schema. See [Use schema transformers](xref:fundamentals/openapi/customize-openapi#use-schema-transformers) for more information.
670670

671+
## Set JSON serialization options globally
672+
673+
The following code configures some JSON options globally, for Minimal APIs and Controler based APIs:
674+
675+
[!code-csharp[](~/fundamentals/openapi/samples/10.x/WebJson/Program.cs?highlight=8-29)]
676+
677+
## MVC JSON options and global JSON options
678+
679+
The following table shows the key Differences beween the MVC JSON options and global Minimal API JSON options:
680+
681+
| **Aspect** | **MVC JSON Options** | **Global JSON Options** |
682+
|-----------------------|--------------------------------------------|-----------------------------------------------|
683+
| **Scope** | Limited to MVC controllers and endpoints. | Minimal Api's and OpenAPI docs. |
684+
| **Configuration** | `AddControllers().AddJsonOptions()` | `Configure<JsonOptions>()` |
685+
| **Purpose** | Handles serialization and deserializtion of JSON requests and responses in APIs. | Defines global JSON handling for Minimal APIs and OpenAPI schemas. |
686+
| **Influence on OpenAPI** | None | Directly influences OpenAPI schema generation.|
687+
688+
---
689+
671690
## Additional resources
672691

673692
* <xref:fundamentals/openapi/using-openapi-documents>
@@ -676,5 +695,3 @@ A schema transformer can be used to override any default metadata or add additio
676695
:::moniker-end
677696

678697
[!INCLUDE[](~/fundamentals/openapi/includes/include-metadata9.md)]
679-
680-
:::moniker-end
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
using Microsoft.AspNetCore.Mvc;
2+
3+
[ApiController]
4+
[Route("[controller]")]
5+
public class TestController : ControllerBase
6+
{
7+
[HttpGet("day")]
8+
public ActionResult<DayOfTheWeekAsString> GetDay()
9+
{
10+
return DayOfTheWeekAsString.Wednesday;
11+
}
12+
13+
[HttpPost("day")]
14+
public IActionResult PostDay(DayOfTheWeekAsString day)
15+
{
16+
return Ok($"Received: {day}");
17+
}
18+
}
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
//using System.Text.Json.Serialization;
2+
//[JsonConverter(typeof(JsonStringEnumConverter<DayOfTheWeekAsString>))]
3+
public enum DayOfTheWeekAsString
4+
{
5+
Sunday,
6+
Monday,
7+
Tuesday,
8+
Wednesday,
9+
Thursday,
10+
Friday,
11+
Saturday
12+
}
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
using System.Text.Json;
2+
using System.Text.Json.Serialization;
3+
using Microsoft.AspNetCore.Http.Json;
4+
5+
var builder = WebApplication.CreateBuilder(args);
6+
7+
builder.Services.AddOpenApi();
8+
9+
builder.Services.Configure<JsonOptions>(options =>
10+
{
11+
options.SerializerOptions.Converters.Add(
12+
new JsonStringEnumConverter<DayOfTheWeekAsString>());
13+
options.SerializerOptions.DefaultIgnoreCondition =
14+
JsonIgnoreCondition.WhenWritingNull;
15+
options.SerializerOptions.PropertyNamingPolicy =
16+
JsonNamingPolicy.CamelCase;
17+
18+
});
19+
20+
builder.Services.AddControllers()
21+
.AddJsonOptions(options =>
22+
{
23+
options.JsonSerializerOptions.Converters.Add(
24+
new JsonStringEnumConverter<DayOfTheWeekAsString>());
25+
options.JsonSerializerOptions.DefaultIgnoreCondition =
26+
JsonIgnoreCondition.WhenWritingNull;
27+
options.JsonSerializerOptions.PropertyNamingPolicy =
28+
JsonNamingPolicy.CamelCase;
29+
});
30+
31+
var app = builder.Build();
32+
33+
if (app.Environment.IsDevelopment())
34+
{
35+
app.MapOpenApi();
36+
}
37+
38+
app.UseHttpsRedirection();
39+
40+
app.MapGet("/", () =>
41+
{
42+
var day = DayOfTheWeekAsString.Friday;
43+
return Results.Json(day);
44+
});
45+
46+
app.MapPost("/", (DayOfTheWeekAsString day) =>
47+
{
48+
return Results.Json($"Received: {day}");
49+
});
50+
51+
app.UseRouting();
52+
app.MapControllers();
53+
54+
app.Run();
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
<Project Sdk="Microsoft.NET.Sdk.Web">
2+
3+
<PropertyGroup>
4+
<TargetFramework>net10.0</TargetFramework>
5+
<Nullable>enable</Nullable>
6+
<ImplicitUsings>enable</ImplicitUsings>
7+
</PropertyGroup>
8+
9+
<ItemGroup>
10+
<PackageReference Include="Microsoft.AspNetCore.OpenApi" Version="10.0.0-preview.3.25172.1" />
11+
</ItemGroup>
12+
13+
</Project>
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
@WebJson_HostAddress = https://localhost:7098
2+
3+
GET {{WebJson_HostAddress}}/
4+
Accept: application/json
5+
6+
### Post doesn't need JsonStringEnumConverter
7+
8+
POST {{WebJson_HostAddress}}/?day=Tuesday
9+
Accept: application/json
10+
11+
###
12+
GET {{WebJson_HostAddress}}/test/day
13+
Accept: application/json
14+
###
15+
16+
### Post doesn't need JsonStringEnumConverter
17+
POST {{WebJson_HostAddress}}/test/day?day=Friday
18+
Content-Type: application/json
19+
20+
###
Lines changed: 117 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,117 @@
1+
{
2+
"openapi": "3.1.1",
3+
"info": {
4+
"title": "WebJson | v1",
5+
"version": "1.0.0"
6+
},
7+
"servers": [
8+
{
9+
"url": "https://localhost:7098/"
10+
}
11+
],
12+
"paths": {
13+
"/": {
14+
"get": {
15+
"tags": [
16+
"WebJson"
17+
],
18+
"responses": {
19+
"200": {
20+
"description": "OK"
21+
}
22+
}
23+
},
24+
"post": {
25+
"tags": [
26+
"WebJson"
27+
],
28+
"parameters": [
29+
{
30+
"name": "day",
31+
"in": "query",
32+
"required": true,
33+
"schema": {
34+
"$ref": "#/components/schemas/DayOfTheWeekAsString"
35+
}
36+
}
37+
],
38+
"responses": {
39+
"200": {
40+
"description": "OK"
41+
}
42+
}
43+
}
44+
},
45+
"/Test/day": {
46+
"get": {
47+
"tags": [
48+
"Test"
49+
],
50+
"responses": {
51+
"200": {
52+
"description": "OK",
53+
"content": {
54+
"text/plain": {
55+
"schema": {
56+
"$ref": "#/components/schemas/DayOfTheWeekAsString"
57+
}
58+
},
59+
"application/json": {
60+
"schema": {
61+
"$ref": "#/components/schemas/DayOfTheWeekAsString"
62+
}
63+
},
64+
"text/json": {
65+
"schema": {
66+
"$ref": "#/components/schemas/DayOfTheWeekAsString"
67+
}
68+
}
69+
}
70+
}
71+
}
72+
},
73+
"post": {
74+
"tags": [
75+
"Test"
76+
],
77+
"parameters": [
78+
{
79+
"name": "day",
80+
"in": "query",
81+
"schema": {
82+
"$ref": "#/components/schemas/DayOfTheWeekAsString"
83+
}
84+
}
85+
],
86+
"responses": {
87+
"200": {
88+
"description": "OK"
89+
}
90+
}
91+
}
92+
}
93+
},
94+
"components": {
95+
"schemas": {
96+
"DayOfTheWeekAsString": {
97+
"enum": [
98+
"Sunday",
99+
"Monday",
100+
"Tuesday",
101+
"Wednesday",
102+
"Thursday",
103+
"Friday",
104+
"Saturday"
105+
]
106+
}
107+
}
108+
},
109+
"tags": [
110+
{
111+
"name": "WebJson"
112+
},
113+
{
114+
"name": "Test"
115+
}
116+
]
117+
}

0 commit comments

Comments
 (0)