namespace System.Text.Json
{
- public enum DuplicatePropertyNameHandling
+ public enum DuplicatePropertyNameHandlingStrategy
{
Replace = 0,
Ignore = 1,
public static implicit operator System.Text.Json.JsonNode (uint value) { throw null; }
[System.CLSCompliantAttribute(false)]
public static implicit operator System.Text.Json.JsonNode (ulong value) { throw null; }
- public static System.Text.Json.JsonNode Parse(string json, System.Text.Json.JsonDocumentOptions options = default(System.Text.Json.JsonDocumentOptions), System.Text.Json.DuplicatePropertyNameHandling duplicatePropertyNameHandling = System.Text.Json.DuplicatePropertyNameHandling.Replace) { throw null; }
+ public static System.Text.Json.JsonNode Parse(string json, System.Text.Json.JsonNodeOptions options = default(System.Text.Json.JsonNodeOptions)) { throw null; }
public string ToJsonString() { throw null; }
public static bool TryGetNode(System.Text.Json.JsonElement jsonElement, out System.Text.Json.JsonNode jsonNode) { throw null; }
public void WriteTo(System.Text.Json.Utf8JsonWriter writer) { }
}
+ public partial struct JsonNodeOptions
+ {
+ private int _dummyPrimitive;
+ public bool AllowTrailingCommas { readonly get { throw null; } set { } }
+ public System.Text.Json.JsonCommentHandling CommentHandling { readonly get { throw null; } set { } }
+ public System.Text.Json.DuplicatePropertyNameHandlingStrategy DuplicatePropertyNameHandling { readonly get { throw null; } set { } }
+ public int MaxDepth { readonly get { throw null; } set { } }
+ }
public sealed partial class JsonNull : System.Text.Json.JsonNode, System.IEquatable<System.Text.Json.JsonNull>
{
public JsonNull() { }
<Reference Include="System.Threading.Tasks.Extensions" />
</ItemGroup>
<ItemGroup>
- <Compile Include="System\Text\Json\Node\DuplicatePropertyNameHandling.cs" />
+ <Compile Include="System\Text\Json\Node\DuplicatePropertyNameHandlingStrategy.cs" />
<Compile Include="System\Text\Json\Node\JsonArray.cs" />
<Compile Include="System\Text\Json\Node\JsonArrayEnumerator.cs" />
<Compile Include="System\Text\Json\Node\JsonBoolean.cs" />
<Compile Include="System\Text\Json\Node\JsonNode.cs" />
<Compile Include="System\Text\Json\Node\JsonNode.Traversal.cs" />
<Compile Include="System\Text\Json\Node\JsonNode.TraversalHelpers.cs" />
+ <Compile Include="System\Text\Json\Node\JsonNodeOptions.cs" />
<Compile Include="System\Text\Json\Node\JsonNull.cs" />
<Compile Include="System\Text\Json\Node\JsonNumber.cs" />
<Compile Include="System\Text\Json\Node\JsonObject.cs" />
-namespace System.Text.Json
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+namespace System.Text.Json
{
/// <summary>
- /// Specifies how duplicate property names are handled when added to JSON object.
+ /// Specifies how duplicate property names are handled when added to a JSON object.
/// </summary>
- public enum DuplicatePropertyNameHandling
+ public enum DuplicatePropertyNameHandlingStrategy
{
/// <summary>
/// Replace the existing value when there is a duplicate property. The value of the last property in the JSON object will be used.
/// Parses a string representing JSON document into <see cref="JsonNode"/>.
/// </summary>
/// <param name="json">JSON to parse.</param>
- /// <param name="options">Options to control the reader behavior during parsing.</param>
- /// <param name="duplicatePropertyNameHandling">Specifies the way of handling duplicate property names.</param>
+ /// <param name="options">Options to control the parsing behavior.</param>
/// <returns><see cref="JsonNode"/> representation of <paramref name="json"/>.</returns>
- public static JsonNode Parse(string json, JsonDocumentOptions options = default, DuplicatePropertyNameHandling duplicatePropertyNameHandling = DuplicatePropertyNameHandling.Replace)
+ public static JsonNode Parse(string json, JsonNodeOptions options = default)
{
Utf8JsonReader reader = new Utf8JsonReader(Encoding.UTF8.GetBytes(json), options.GetReaderOptions());
}
else
{
- AddToParent(newProperty, ref currentNodes, ref toReturn, duplicatePropertyNameHandling);
+ AddToParent(newProperty, ref currentNodes, ref toReturn, options.DuplicatePropertyNameHandling);
}
}
Debug.Assert(currentPair.Value is JsonObject);
currentNodes.Pop();
- AddToParent(currentPair, ref currentNodes, ref toReturn, duplicatePropertyNameHandling);
+ AddToParent(currentPair, ref currentNodes, ref toReturn, options.DuplicatePropertyNameHandling);
break;
case JsonTokenType.StartArray:
AddNewPair(new JsonArray(), true);
Debug.Assert(currentPair.Value is JsonArray);
currentNodes.Pop();
- AddToParent(currentPair, ref currentNodes, ref toReturn, duplicatePropertyNameHandling);
+ AddToParent(currentPair, ref currentNodes, ref toReturn, options.DuplicatePropertyNameHandling);
break;
case JsonTokenType.PropertyName:
currentNodes.Push(new KeyValuePair<string, JsonNode>(reader.GetString(), null));
KeyValuePair<string, JsonNode> nodePair,
ref Stack<KeyValuePair<string, JsonNode>> currentNodes,
ref JsonNode toReturn,
- DuplicatePropertyNameHandling duplicatePropertyNameHandling = DuplicatePropertyNameHandling.Replace)
+ DuplicatePropertyNameHandlingStrategy duplicatePropertyNameHandling = DuplicatePropertyNameHandlingStrategy.Replace)
{
if (currentNodes.Any())
{
// Handle duplicate properties accordingly to duplicatePropertyNameHandling:
- if (duplicatePropertyNameHandling == DuplicatePropertyNameHandling.Replace)
+ if (duplicatePropertyNameHandling == DuplicatePropertyNameHandlingStrategy.Replace)
{
jsonObject[nodePair.Key] = nodePair.Value;
}
else if (jsonObject._dictionary.ContainsKey(nodePair.Key))
{
- if (duplicatePropertyNameHandling == DuplicatePropertyNameHandling.Error)
+ if (duplicatePropertyNameHandling == DuplicatePropertyNameHandlingStrategy.Error)
throw new ArgumentException(SR.JsonObjectDuplicateKey);
- Debug.Assert(duplicatePropertyNameHandling == DuplicatePropertyNameHandling.Ignore);
+ Debug.Assert(duplicatePropertyNameHandling == DuplicatePropertyNameHandlingStrategy.Ignore);
}
else
{
--- /dev/null
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+using System.Diagnostics;
+
+namespace System.Text.Json
+{
+ /// <summary>
+ /// Provides the ability for the user to define custom behavior when parsing JSON to create a <see cref="JsonNode"/>.
+ /// </summary>
+ public struct JsonNodeOptions
+ {
+ internal const int DefaultMaxDepth = 64;
+
+ private int _maxDepth;
+ private JsonCommentHandling _commentHandling;
+
+ /// <summary>
+ /// Gets or sets a value that determines how the <see cref="JsonNode"/> handles comments when reading through the JSON data.
+ /// </summary>
+ /// <exception cref="ArgumentOutOfRangeException">
+ /// The comment handling enum is set to a value that is not supported (or not within the <see cref="JsonCommentHandling"/> enum range).
+ /// </exception>
+ /// <remarks>
+ /// By default <exception cref="JsonException"/> is thrown if a comment is encountered.
+ /// </remarks>
+ public JsonCommentHandling CommentHandling
+ {
+ readonly get => _commentHandling;
+ set
+ {
+ Debug.Assert(value >= 0);
+ if (value > JsonCommentHandling.Skip)
+ throw new ArgumentOutOfRangeException(nameof(value), SR.JsonDocumentDoesNotSupportComments);
+
+ _commentHandling = value;
+ }
+ }
+
+ /// <summary>
+ /// Gets or sets the maximum depth allowed when parsing JSON data,
+ /// with the default (that is, 0) indicating a maximum depth of 64.
+ /// </summary>
+ /// <exception cref="ArgumentOutOfRangeException">
+ /// The max depth is set to a negative value.
+ /// </exception>
+ /// <value>
+ /// The maximum depth allowed when parsing JSON data.
+ /// </value>
+ /// <remarks>
+ /// Parsing past this depth will throw a <exception cref="JsonException"/>.
+ /// </remarks>
+ public int MaxDepth
+ {
+ readonly get => _maxDepth;
+ set
+ {
+ if (value < 0)
+ throw ThrowHelper.GetArgumentOutOfRangeException_MaxDepthMustBePositive(nameof(value));
+
+ _maxDepth = value;
+ }
+ }
+
+ /// <summary>
+ /// Gets or sets a value that indicates whether an extra comma at the end of a list of JSON values
+ /// in an object or array is allowed (and ignored) within the JSON payload being read.
+ /// </summary>
+ /// <returns>
+ /// <see langword="true"/> if an extra comma at the end of a list of JSON values in an object or array is allowed;
+ /// otherwise, <see langword="false"/>. Default is <see langword="false"/>.
+ /// </returns>
+ /// <remarks>
+ /// By default, it's set to false, and <exception cref="JsonException"/> is thrown if a trailing comma is encountered.
+ /// </remarks>
+ public bool AllowTrailingCommas { get; set; }
+
+ private DuplicatePropertyNameHandlingStrategy _duplicatePropertyNameHandlingStrategy;
+
+ /// <summary>
+ /// Gets or sets the duplicate property name handling strategy.
+ /// </summary>
+ /// <remarks>
+ /// By default, it's set to <exception cref="DuplicatePropertyNameHandlingStrategy.Replace"/>.
+ /// </remarks>
+ public DuplicatePropertyNameHandlingStrategy DuplicatePropertyNameHandling
+ {
+ readonly get => _duplicatePropertyNameHandlingStrategy;
+ set
+ {
+ if ((uint)value > (uint)DuplicatePropertyNameHandlingStrategy.Error)
+ throw new ArgumentOutOfRangeException(SR.InvalidDuplicatePropertyNameHandling);
+
+ _duplicatePropertyNameHandlingStrategy = value;
+ }
+ }
+
+ internal JsonReaderOptions GetReaderOptions()
+ {
+ return new JsonReaderOptions
+ {
+ AllowTrailingCommas = AllowTrailingCommas,
+ CommentHandling = CommentHandling,
+ MaxDepth = MaxDepth
+ };
+ }
+ }
+}
{
protected override JsonDocument PrepareDocument(string jsonIn)
{
- JsonNode jsonNode = JsonNode.Parse(jsonIn, s_options);
+ JsonNode jsonNode = JsonNode.Parse(jsonIn, new JsonNodeOptions
+ {
+ AllowTrailingCommas = s_options.AllowTrailingCommas,
+ CommentHandling = s_options.CommentHandling,
+ MaxDepth = s_options.MaxDepth
+ });
using (MemoryStream stream = new MemoryStream())
{
builder.Append("]");
}
- var options = new JsonDocumentOptions { MaxDepth = 5_000 };
+ var options = new JsonNodeOptions { MaxDepth = 5_000 };
JsonNode jsonNode = JsonNode.Parse(builder.ToString(), options);
}
Assert.Equal(2, jsonObject.GetPropertyValues().Count);
Assert.Equal("last duplicate value", jsonObject["property"]);
- jsonObject = (JsonObject) JsonNode.Parse(stringWithDuplicates, default, DuplicatePropertyNameHandling.Replace);
+ jsonObject = (JsonObject) JsonNode.Parse(stringWithDuplicates, new JsonNodeOptions() { DuplicatePropertyNameHandling = DuplicatePropertyNameHandlingStrategy.Replace });
Assert.Equal(2, jsonObject.GetPropertyNames().Count);
Assert.Equal(2, jsonObject.GetPropertyValues().Count);
Assert.Equal("last duplicate value", jsonObject["property"]);
- jsonObject = (JsonObject)JsonNode.Parse(stringWithDuplicates, default, DuplicatePropertyNameHandling.Ignore);
+ jsonObject = (JsonObject)JsonNode.Parse(stringWithDuplicates, new JsonNodeOptions() { DuplicatePropertyNameHandling = DuplicatePropertyNameHandlingStrategy.Ignore });
Assert.Equal(2, jsonObject.GetPropertyNames().Count);
Assert.Equal(2, jsonObject.GetPropertyValues().Count);
Assert.Equal("first value", jsonObject["property"]);
- Assert.Throws<ArgumentException>(() => JsonNode.Parse(stringWithDuplicates, default, DuplicatePropertyNameHandling.Error));
+ Assert.Throws<ArgumentException>(() => JsonNode.Parse(stringWithDuplicates, new JsonNodeOptions() { DuplicatePropertyNameHandling = DuplicatePropertyNameHandlingStrategy.Error }));
}
}
}