Reduce verbosity and pain for working with JSON in C# #8535
-
Consider this JSON:
Let's check if it has entries property, and the entries property is array and it has at least one element, then get the message property if it exists. This is the JS code:
This is the Python code:
More verbose, but still bearable. This is the C# code:
See the amount of verbosity? More lines of code and less readability. Please make working with JSON less verbose. Please enhance the DX in working with JSON in C#. It's a pain. This is a pseudo-code that could be valuable:
|
Beta Was this translation helpful? Give feedback.
Replies: 9 comments 23 replies
-
I encourage others to add samples from more languages to see how bad C# is in this regard. I asked ChatGPT and these are some more code examples: Ruby:
PHP:
Dart:
Kotlin:
I don't know if they are valid codes or not. I'm not an expert in those languages. But if they are valid, then C# is truly awful in handling JSON. |
Beta Was this translation helpful? Give feedback.
-
This sounds like you're requesting a library change, not a language / syntax change. I.e., you want the Should that be the case, I'd advise you to forward your question/issue to the following repo: |
Beta Was this translation helpful? Give feedback.
-
I think active patterns would solve this quite nicely. I fail to find the proposal though.. Being able to do something like this: var json = ParseJson(jsongString);
if (json is JsonArray { entries: [{} firstEntry] } && firstEntry.TryGetProperty("message", out JsonElement message))
{
var message = message.GetString();
} Where |
Beta Was this translation helpful? Give feedback.
-
I think the using System.Text.Json;
using System.Text.Json.Nodes;
var json = JsonSerializer.Deserialize<JsonNode>(jsonString);
if (json["entries"] is JsonArray array && array.Count > 0)
{
var message = array[0]["message"].GetValue<string>();
} |
Beta Was this translation helpful? Give feedback.
-
I doubt that the existing API would introduce such breaking changes but you can use 3rd party solutions if reducing verbosity is really that important (disclaimer: I am the author, so I hope this is not qualified as an unwanted advertisement). With the library above the solution is this compact (see also online): var json = JsonValue.Parse(jsonString);
string message = json["entries"][0]["message"].AsString ?? throw new ArgumentException("Invalid content"); You can do this because getting lost in the hierarchy just returns a default Console.WriteLine(json["entrdries"][-42]["msg"]); // undefined And here you can compare the verbosity of the different libraries (well, this is when there is no validation; otherwise, other libraries are just even more verbose). |
Beta Was this translation helpful? Give feedback.
-
How about a struct wrapper of public readonly struct JsonElementWrapper(JsonElement element)
{
public JsonElementWrapper? this[int index] => element.ValueKind is JsonValueKind.Array ? new(element[index]) : null;
public JsonElementWrapper? this[ReadOnlySpan<char> propertyName] => element.ValueKind is JsonValueKind.Object ? new(element.GetProperty(propertyName)) : null;
public int? ArrayLength => element.ValueKind is JsonValueKind.Array ? element.GetArrayLength() : null;
public string? AsString() => element.ValueKind is JsonValueKind.String ? element.GetString() : null;
} and you can write using var doc = JsonDocument.Parse(jsonString);
var root = new JsonElementWrapper(doc.RootElement);
if (root["entries"] is { ArrayLength: > 0 } entries) {
var message = entries[0]?["message"]?.AsString();
} |
Beta Was this translation helpful? Give feedback.
-
I think you think it's long because you used the wrong API. using Newtonsoft.Json.Linq;
JObject json = JObject.Parse(jsonString);
if (json["entries"] is JArray { Count: > 0 } jar)
{
Console.WriteLine(jar[0]["message"]);
} |
Beta Was this translation helpful? Give feedback.
-
Seems easy enough to manage this fluently using the public static string? GetMessage(string json) =>
JsonDocument.Parse(json).RootElement
.GetProperty("entries")
.EnumerateArray()
.FirstOrDefault()
.GetProperty("message")
.GetString(); Arugably more readable and easier on the eyes than the JS/Python/other languages above. |
Beta Was this translation helpful? Give feedback.
-
Closing out as this has been answered. There are incredibly simple ways of working with Jason that people have already provided. And this is due to the support the language gives you. If you want particular apis to integrate better with the language support, you should take it up with the API authors. The language already has the tools to make the consumption as nice (or nicer) than the examples you provided from other languages. |
Beta Was this translation helpful? Give feedback.
This can be further simplified with list pattern: