-
Notifications
You must be signed in to change notification settings - Fork 5.2k
Description
JsonDocument
This class holds the parsed model of the JSON payload. It rents storage from an array pool, and this is IDisposable
to return the resources back.
Like XmlDocument, this type only really has a creation routine (Parse
) and access to the root element.
An instance takes a ReadOnlyMemory during construction, and holds that ReadOnlyMemory until Dispose (caller modification of the data between Parse and Dispose leads to non-deterministic, unsupported behavior).
JsonElement
This type is effectively a cursor in the document. It is tied to the document that created it, so when that document gets disposed the ObjectDisposedException
s leak out from this types members. To keep memory utilization at a minimum it is a struct which is effectively a union of what would otherwise be JsonArray, JsonObject, JsonComment, JsonString, JsonNumber, JsonProperty, and whatever we'd do for true
/false
/null
.
Update
Based on the previous API review:
- JsonDocument.Parse now also accepts
string
,ReadOnlySpan<char>
, andReadOnlySequence<byte>
, and manages things appropriately. - (Try)GetRawBytes is gone
- TryGetValue overloads are now Try-prefixed versions of the non-Try methods (e.g. TryGetInt32())
- [Try]GetDecimal was added
- [Try]GetSingle and [Try]GetUInt32 were added
- The string (and
ReadOnlySpan<char>
andReadOnlySpan<byte>
) indexer(s) are now aGetProperty
method group to convey that they're more than O(1) expensive. - Split EnumerateChildren to EnumerateArray and EnumerateObject.
- Custom enumerable/enumerators now implement the interfaces
- EnumerateObject gets JsonProperty values instead of JsonElement (name is delay allocated as a System.String)
- Added JsonValueType, which is JsonTokenType except
- StartObject => Object
- StartArray => Array
- None => Undefined (to match the ECMAScript undefined value)
- -EndObject
- -EndArray
- -Comment
- JsonReaderOptions inputs to JsonDocument.Parse are defaulted to default
Changes NOT made:
- No first-class support for nullable at this time
- The property indexer (now deleted) does not return a nullable JsonElement, because neither the indexer nor methods lifted
namespace System.Text.Json
{
public sealed partial class JsonDocument : IDisposable
{
public JsonElement RootElement { get; }
public void Dispose();
public static JsonDocument Parse(ReadOnlySequence<byte> utf8Json, JsonReaderOptions readerOptions = default);
public static JsonDocument Parse(System.ReadOnlyMemory<byte> utf8Json, JsonReaderOptions readerOptions = default);
public static JsonDocument Parse(System.ReadOnlyMemory<char> json, JsonReaderOptions readerOptions = default);
public static JsonDocument Parse(string json, JsonReaderOptions readerOptions = default);
}
public readonly partial struct JsonElement
{
// InvalidOperationException if Type is not Array
// IndexOutOfRangeException when appropriate
public JsonElement this[int index] { get; }
public JsonValueType Type { get; }
// InvalidOperationException if Type is not Array
public JsonElement.ArrayEnumerator EnumerateArray();
public int GetArrayLength();
// InvalidOperationException if Type is not Object
public JsonElement.ObjectEnumerator EnumerateObject();
public bool TryGetProperty(ReadOnlySpan<byte> utf8PropertyName, out JsonElement value);
public bool TryGetProperty(ReadOnlySpan<char> propertyName, out JsonElement value);
public bool TryGetProperty(string propertyName, out JsonElement value);
// KeyNotFoundException if the property is not found
public JsonElement GetProperty(ReadOnlySpan<byte> utf8PropertyName);
public JsonElement GetProperty(ReadOnlySpan<char> propertyName);
public JsonElement GetProperty(string propertyName);
// InvalidOperationException if Type is not True or False
public bool GetBoolean();
// InvalidOperationException if Type is not Number
// FormatException if value does not fit
public decimal GetDecimal();
public double GetDouble();
public int GetInt32();
public long GetInt64();
public float GetSingle();
public string GetString();
[CLSCompliantAttribute(false)]
public uint GetUInt32();
[CLSCompliantAttribute(false)]
public ulong GetUInt64();
// InvalidOperationException if Type is not Number
// false if value does not fit.
public bool TryGetDecimal(out decimal value);
public bool TryGetDouble(out double value);
public bool TryGetInt32(out int value);
public bool TryGetInt64(out long value);
public bool TryGetSingle(out float value);
[CLSCompliantAttribute(false)]
public bool TryGetUInt32(out uint value);
[CLSCompliantAttribute(false)]
public bool TryGetUInt64(out ulong value);
public override string ToString();
public partial struct ArrayEnumerator : IEnumerable<JsonElement>, IEnumerator<JsonElement>, IEnumerable, IEnumerator, IDisposable
{
public JsonElement Current { get; }
public void Dispose();
public JsonElement.ArrayEnumerator GetEnumerator();
public bool MoveNext();
public void Reset();
}
public partial struct ObjectEnumerator : IEnumerable<JsonProperty>, IEnumerator<JsonProperty>, IEnumerable, IEnumerator, IDisposable
{
public JsonProperty Current { get; }
public void Dispose();
public JsonElement.ObjectEnumerator GetEnumerator();
public bool MoveNext();
public void Reset();
}
}
public partial readonly struct JsonProperty
{
public string Name { get; }
public JsonElement Value { get; }
}
public enum JsonValueType : byte
{
Array = (byte)2,
False = (byte)6,
Null = (byte)7,
Number = (byte)4,
Object = (byte)1,
String = (byte)3,
True = (byte)5,
Undefined = (byte)0,
}
public partial struct Utf8JsonWriter
{
public void WriteElement(string propertyName, JsonElement value);
public void WriteElement(ReadOnlySpan<char> propertyName, JsonElement value);
public void WriteElement(ReadOnlySpan<byte> propertyName, JsonElement value);
public void WriteElementValue(JsonElement element);
}
}
In order to keep the overhead low this type does not support data manipulation (insert/append, delete, or update).