@@ -27,6 +27,165 @@ JSON.parse("[{a:1}]") //= new List<object> { new Dictionary<string, object> { {
2727
2828It can be used to parse dynamic JSON and any primitive JavaScript data type. The inverse API of ` JSON.stringify() ` is also available.
2929
30+ ## Use C# Pattern Matching
31+
32+ ### Getting the client_id in a ComfyUI Output
33+
34+ ``` csharp
35+ var comfyOutput = JSON .parse (json );
36+ var promptId = comfyOutput .Keys .First ();
37+ var prompt = (Dictionary <string , object ?>)comfyOutput [promptId ]! ;
38+ if (prompt .TryGetValue (" prompt" , out var oPromptTuple ) && oPromptTuple is List <object > promptTuple )
39+ {
40+ if (promptTuple .Count > 3 )
41+ {
42+ var extraData = promptTuple [3 ];
43+ if (extraData is Dictionary <string , object ?> extraDataDict )
44+ {
45+ if (extraDataDict .TryGetValue (" client_id" , out var oClientId ))
46+ {
47+ return oClientId as string ;
48+ }
49+ }
50+ }
51+ }
52+ return null ;
53+ ```
54+
55+ Equivalent implementation using System.Text.Json:
56+
57+ ``` csharp
58+ using System .Text .Json ;
59+
60+ var jsonDocument = JsonDocument .Parse (json );
61+ var root = jsonDocument .RootElement ;
62+
63+ var promptId = root .EnumerateObject ().FirstOrDefault ().Name ;
64+ if (! string .IsNullOrEmpty (promptId ) && root .TryGetProperty (promptId , out var promptElement ))
65+ {
66+ if (promptElement .TryGetProperty (" prompt" , out var promptTupleElement )
67+ && promptTupleElement .ValueKind == JsonValueKind .Array )
68+ {
69+ var promptArray = promptTupleElement .EnumerateArray ().ToArray ();
70+ if (promptArray .Length > 3 )
71+ {
72+ var extraDataElement = promptArray [3 ];
73+ if (extraDataElement .ValueKind == JsonValueKind .Object
74+ && extraDataElement .TryGetProperty (" client_id" , out var clientIdElement )
75+ && clientIdElement .ValueKind == JsonValueKind .String )
76+ {
77+ return clientIdElement .GetString ();
78+ }
79+ }
80+ }
81+ }
82+ return null ;
83+ ```
84+
85+ ### Parsing a Gemini API Request
86+
87+ As JSON Object just stored any JSON into untyped generic collections you can use C# pattern matching to navigate and mutate the JSON Object as done in this example which modifies an Gemini API Request to replace the ` inline_data.data ` string with its length to make it suitable for logging:
88+
89+ ``` csharp
90+ var obj = (Dictionary <string ,object >) JSON .parse (json );
91+ if (obj .TryGetValue (" contents" , out var oContents )
92+ && oContents is List <object > contents )
93+ {
94+ foreach (var oContent in contents )
95+ {
96+ if (oContent is Dictionary <string , object > content
97+ && content .TryGetValue (" parts" , out var oParts )
98+ && oParts is List <object > parts )
99+ {
100+ foreach (var oPart in parts )
101+ {
102+ if (oPart is Dictionary <string , object > part
103+ && part .TryGetValue (" inline_data" , out var oInlineData )
104+ && oInlineData is Dictionary <string , object > inlineData
105+ && inlineData .TryGetValue (" data" , out var oData )
106+ && oData is string data )
107+ {
108+ inlineData [" data" ] = $" ({data .Length })" ;
109+ }
110+ }
111+ }
112+ }
113+ }
114+ Console .WriteLine (JSON .stringify (obj ));
115+ ```
116+
117+ This would be an equivalent implementation using System.Text.Json:
118+
119+ ``` csharp
120+ using System .Text .Json ;
121+
122+ var jsonDocument = JsonDocument .Parse (json );
123+ var root = jsonDocument .RootElement ;
124+
125+ if (root .TryGetProperty (" contents" , out var contentsElement )
126+ && contentsElement .ValueKind == JsonValueKind .Array )
127+ {
128+ foreach (var contentElement in contentsElement .EnumerateArray ())
129+ {
130+ if (contentElement .ValueKind == JsonValueKind .Object
131+ && contentElement .TryGetProperty (" parts" , out var partsElement )
132+ && partsElement .ValueKind == JsonValueKind .Array )
133+ {
134+ foreach (var partElement in partsElement .EnumerateArray ())
135+ {
136+ if (partElement .ValueKind == JsonValueKind .Object
137+ && partElement .TryGetProperty (" inline_data" , out var inlineDataElement )
138+ && inlineDataElement .ValueKind == JsonValueKind .Object
139+ && inlineDataElement .TryGetProperty (" data" , out var dataElement )
140+ && dataElement .ValueKind == JsonValueKind .String )
141+ {
142+ var data = dataElement .GetString ();
143+ // Note: System.Text.Json JsonDocument is read-only
144+ // To modify, you'd need to reconstruct the JSON or use JsonNode
145+ Console .WriteLine ($" Data length: {data ? .Length }" );
146+ }
147+ }
148+ }
149+ }
150+ }
151+ ```
152+
153+ But as it's a read-only data structure you'd need to reconstruct the JSON to modify it. To create an equivalent modified JSON for logging, you can use ` JsonNode ` for mutable operations:
154+
155+ ``` csharp
156+ using System .Text .Json ;
157+ using System .Text .Json .Nodes ;
158+
159+ var jsonNode = JsonNode .Parse (json );
160+
161+ if (jsonNode is JsonObject rootObj
162+ && rootObj [" contents" ] is JsonArray contentsArray )
163+ {
164+ foreach (var contentNode in contentsArray )
165+ {
166+ if (contentNode is JsonObject contentObj
167+ && contentObj [" parts" ] is JsonArray partsArray )
168+ {
169+ foreach (var partNode in partsArray )
170+ {
171+ if (partNode is JsonObject partObj
172+ && partObj [" inline_data" ] is JsonObject inlineDataObj
173+ && inlineDataObj [" data" ] is JsonValue dataValue
174+ && dataValue .TryGetValue <string >(out var data ))
175+ {
176+ // Modify the data for logging
177+ inlineDataObj [" data" ] = $" ({data .Length })" ;
178+ }
179+ }
180+ }
181+ }
182+ }
183+
184+ // Output the modified JSON for logging
185+ Console .WriteLine (jsonNode .ToJsonString ());
186+ ```
187+
188+
30189### Register JS Utils in ServiceStack.Text
31190
32191JS Utils is already pre-configured in ServiceStack Web Apps to handle serializing & deserializing ` object ` types.
0 commit comments