1+ // Licensed to the .NET Foundation under one or more agreements.
2+ // The .NET Foundation licenses this file to you under the MIT license.
3+
4+ using System . Diagnostics . CodeAnalysis ;
5+ using System . Text . Json ;
6+ using System . Text . Json . Serialization ;
7+
8+ namespace Microsoft . Azure . Functions . Worker . Http ;
9+
10+ internal sealed class ProblemDetailsJsonConverter : JsonConverter < ProblemDetails >
11+ {
12+ private static readonly JsonEncodedText Type = JsonEncodedText . Encode ( "type" ) ;
13+ private static readonly JsonEncodedText Title = JsonEncodedText . Encode ( "title" ) ;
14+ private static readonly JsonEncodedText Status = JsonEncodedText . Encode ( "status" ) ;
15+ private static readonly JsonEncodedText Detail = JsonEncodedText . Encode ( "detail" ) ;
16+ private static readonly JsonEncodedText Instance = JsonEncodedText . Encode ( "instance" ) ;
17+
18+ public override ProblemDetails Read ( ref Utf8JsonReader reader , Type typeToConvert , JsonSerializerOptions options )
19+ {
20+ var problemDetails = new ProblemDetails ( ) ;
21+
22+ if ( reader . TokenType != JsonTokenType . StartObject )
23+ {
24+ throw new JsonException ( "Unexcepted end when reading JSON." ) ;
25+ }
26+
27+ while ( reader . Read ( ) && reader . TokenType != JsonTokenType . EndObject )
28+ {
29+ ReadValue ( ref reader , problemDetails , options ) ;
30+ }
31+
32+ if ( reader . TokenType != JsonTokenType . EndObject )
33+ {
34+ throw new JsonException ( "Unexcepted end when reading JSON." ) ;
35+ }
36+
37+ return problemDetails ;
38+ }
39+
40+ public override void Write ( Utf8JsonWriter writer , ProblemDetails value , JsonSerializerOptions options )
41+ {
42+ writer . WriteStartObject ( ) ;
43+ WriteProblemDetails ( writer , value , options ) ;
44+ writer . WriteEndObject ( ) ;
45+ }
46+
47+ internal static void ReadValue ( ref Utf8JsonReader reader , ProblemDetails value , JsonSerializerOptions options )
48+ {
49+ if ( TryReadStringProperty ( ref reader , Type , out var propertyValue ) )
50+ {
51+ value . Type = propertyValue ;
52+ }
53+ else if ( TryReadStringProperty ( ref reader , Title , out propertyValue ) )
54+ {
55+ value . Title = propertyValue ;
56+ }
57+ else if ( TryReadStringProperty ( ref reader , Detail , out propertyValue ) )
58+ {
59+ value . Detail = propertyValue ;
60+ }
61+ else if ( TryReadStringProperty ( ref reader , Instance , out propertyValue ) )
62+ {
63+ value . Instance = propertyValue ;
64+ }
65+ else if ( reader . ValueTextEquals ( Status . EncodedUtf8Bytes ) )
66+ {
67+ reader . Read ( ) ;
68+ if ( reader . TokenType == JsonTokenType . Null )
69+ {
70+ // Nothing to do here.
71+ }
72+ else
73+ {
74+ value . Status = reader . GetInt32 ( ) ;
75+ }
76+ }
77+ else
78+ {
79+ var key = reader . GetString ( ) ! ;
80+ reader . Read ( ) ;
81+ value . Extensions [ key ] = JsonSerializer . Deserialize ( ref reader , typeof ( object ) , options ) ;
82+ }
83+ }
84+
85+ internal static bool TryReadStringProperty ( ref Utf8JsonReader reader , JsonEncodedText propertyName , [ NotNullWhen ( true ) ] out string ? value )
86+ {
87+ if ( ! reader . ValueTextEquals ( propertyName . EncodedUtf8Bytes ) )
88+ {
89+ value = default ;
90+ return false ;
91+ }
92+
93+ reader . Read ( ) ;
94+ value = reader . GetString ( ) ! ;
95+ return true ;
96+ }
97+
98+ internal static void WriteProblemDetails ( Utf8JsonWriter writer , ProblemDetails value , JsonSerializerOptions options )
99+ {
100+ if ( value . Type != null )
101+ {
102+ writer . WriteString ( Type , value . Type ) ;
103+ }
104+
105+ if ( value . Title != null )
106+ {
107+ writer . WriteString ( Title , value . Title ) ;
108+ }
109+
110+ if ( value . Status != null )
111+ {
112+ writer . WriteNumber ( Status , value . Status . Value ) ;
113+ }
114+
115+ if ( value . Detail != null )
116+ {
117+ writer . WriteString ( Detail , value . Detail ) ;
118+ }
119+
120+ if ( value . Instance != null )
121+ {
122+ writer . WriteString ( Instance , value . Instance ) ;
123+ }
124+
125+ foreach ( var kvp in value . Extensions )
126+ {
127+ writer . WritePropertyName ( kvp . Key ) ;
128+ JsonSerializer . Serialize ( writer , kvp . Value , kvp . Value ? . GetType ( ) ?? typeof ( object ) , options ) ;
129+ }
130+ }
131+ }
0 commit comments