I have some JSON that includes comments (even though comments aren't strictly allowed in the JSON spec.) How can I parse this JSON using System.Text.Json
?
The JSON I have received is as folows:
// A person
{
"Id" : 1 /* Person's ID */,
"Name" : "Foo" // Person's name
}
When I attempt to load it into a JsonDocument
like so:
using var doc = JsonDocument.Parse(jsonString);
I get the following exception:
System.Text.Json.JsonReaderException: '/' is an invalid start of a value. LineNumber: 0 | BytePositionInLine: 0. at System.Text.Json.ThrowHelper.ThrowJsonReaderException(Utf8JsonReader& json, ExceptionResource resource, Byte nextByte, ReadOnlySpan`1 bytes) at System.Text.Json.Utf8JsonReader.ConsumeValue(Byte marker)```
And when I attempt to deserialize with JsonSerializer
:
var person = JsonSerializer.Deserialize<Person>(jsonString);
I get a similar exception:
System.Text.Json.JsonException: '/' is an invalid start of a value. Path: $ | LineNumber: 0 | BytePositionInLine: 0. ---> System.Text.Json.JsonReaderException: '/' is an invalid start of a value. LineNumber: 0 | BytePositionInLine: 0. at System.Text.Json.ThrowHelper.ThrowJsonReaderException(Utf8JsonReader& json, ExceptionResource resource, Byte nextByte, ReadOnlySpan`1 bytes) at System.Text.Json.Utf8JsonReader.ConsumeValue(Byte marker)
How can I parse or deserialize this JSON with System.Text.Json
?
A common way to deserialize JSON is to first create a class with properties and fields that represent one or more of the JSON properties. Then, to deserialize from a string or a file, call the JsonSerializer. Deserialize method.
Text. Json. Serialization namespace, which contains attributes and APIs for advanced scenarios and customization specific to serialization and deserialization.
Text. Json Namespace. Provides high-performance, low-allocating, and standards-compliant capabilities to process JavaScript Object Notation (JSON), which includes serializing objects to JSON text and deserializing JSON text to objects, with UTF-8 support built-in.
JSON containing comments can be parsed by System.Text.Json
, but by default such JSON is considered invalid, likely since comments are not included in the JSON standard. Support for comments nevertheless can be enabled by modifying the JsonCommentHandling
enum in options:
Disallow 0 Doesn't allow comments within the JSON input. Comments are treated as invalid JSON if found, and a JsonException is thrown. This is the default value. Skip 1 Allows comments within the JSON input and ignores them. The Utf8JsonReader behaves as if no comments are present. Allow 2 Allows comments within the JSON input and treats them as valid tokens. While reading, the caller can access the comment values.
To enable skipping or loading of comments when reading directly with Utf8JsonReader
, set JsonReaderOptions.CommentHandling
in one of the Utf8JsonReader
constructors, e.g. as follows:
static List<string> GetComments(string jsonString)
{
var options = new JsonReaderOptions
{
CommentHandling = JsonCommentHandling.Allow
};
var list = new List<string>();
var reader = new Utf8JsonReader(new ReadOnlySpan<byte>(Encoding.UTF8.GetBytes(jsonString)), options);
while (reader.Read())
if (reader.TokenType == JsonTokenType.Comment)
list.Add(reader.GetComment());
return list;
}
When parsing with JsonDocument
set JsonDocumentOptions.CommentHandling = JsonCommentHandling.Skip
:
var options = new JsonDocumentOptions
{
CommentHandling = JsonCommentHandling.Skip,
};
using var doc = JsonDocument.Parse(jsonString, options);
When deserializing with JsonSerializer
set JsonSerializerOptions.ReadCommentHandling = JsonCommentHandling.Skip
:
var options = new JsonSerializerOptions
{
ReadCommentHandling = JsonCommentHandling.Skip
};
var person = JsonSerializer.Deserialize<Person>(jsonString, options);
Note that, as of .NET Core 3.1, JsonDocument
and JsonSerializer
only support skipping or disallowing of comments; they do not support loading them. If you try to set JsonCommentHandling.Allow
for either, you will get an exception:
System.ArgumentOutOfRangeException: Comments cannot be stored in a JsonDocument, only the Skip and Disallow comment handling modes are supported. (Parameter 'value') System.ArgumentOutOfRangeException: Comments cannot be stored when deserializing objects, only the Skip and Disallow comment handling modes are supported. (Parameter 'value')
(This means that one does not need to manually skip comments when writing a JsonConverter<T>.Read()
method, which simplifies comment processing as compared to Newtonsoft where comments are exposed to ReadJson()
and must be checked for every time a token is read.)
For more see How to serialize and deserialize JSON in .NET : Allow comments and trailing commas.
Demo fiddle here.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With