/// <summary> /// Copies the options from a <see cref="JsonSerializerOptions"/> instance to a new instance. /// </summary> /// <param name="options">The <see cref="JsonSerializerOptions"/> instance to copy options from.</param> /// <exception cref="System.ArgumentNullException"> /// <paramref name="options"/> is <see langword="null"/>. /// </exception> public JsonSerializerOptions(JsonSerializerOptions options) { if (options == null) { throw new ArgumentNullException(nameof(options)); } _memberAccessorStrategy = options._memberAccessorStrategy; _dictionaryKeyPolicy = options._dictionaryKeyPolicy; _jsonPropertyNamingPolicy = options._jsonPropertyNamingPolicy; _readCommentHandling = options._readCommentHandling; _referenceHandler = options._referenceHandler; _encoder = options._encoder; _defaultIgnoreCondition = options._defaultIgnoreCondition; _numberHandling = options._numberHandling; _unknownTypeHandling = options._unknownTypeHandling; _defaultBufferSize = options._defaultBufferSize; _maxDepth = options._maxDepth; _allowTrailingCommas = options._allowTrailingCommas; _ignoreNullValues = options._ignoreNullValues; _ignoreReadOnlyProperties = options._ignoreReadOnlyProperties; _ignoreReadonlyFields = options._ignoreReadonlyFields; _includeFields = options._includeFields; _propertyNameCaseInsensitive = options._propertyNameCaseInsensitive; _writeIndented = options._writeIndented; Converters = new ConverterList(this, (ConverterList)options.Converters); EffectiveMaxDepth = options.EffectiveMaxDepth; ReferenceHandlingStrategy = options.ReferenceHandlingStrategy; // _classes is not copied as sharing the JsonTypeInfo and JsonPropertyInfo caches can result in // unnecessary references to type metadata, potentially hindering garbage collection on the source options. // _haveTypesBeenCreated is not copied; it's okay to make changes to this options instance as (de)serialization has not occurred. TrackOptionsInstance(this); }
/// <summary> /// Copies the options from a <see cref="JsonSerializerOptions"/> instance to a new instance. /// </summary> /// <param name="options">The <see cref="JsonSerializerOptions"/> instance to copy options from.</param> /// <exception cref="System.ArgumentNullException"> /// <paramref name="options"/> is <see langword="null"/>. /// </exception> public JsonSerializerOptions(JsonSerializerOptions options) { if (options is null) { ThrowHelper.ThrowArgumentNullException(nameof(options)); } _memberAccessorStrategy = options._memberAccessorStrategy; _dictionaryKeyPolicy = options._dictionaryKeyPolicy; _jsonPropertyNamingPolicy = options._jsonPropertyNamingPolicy; _readCommentHandling = options._readCommentHandling; _referenceHandler = options._referenceHandler; _converters = new ConverterList(this, options._converters); _encoder = options._encoder; _defaultIgnoreCondition = options._defaultIgnoreCondition; _numberHandling = options._numberHandling; _unknownTypeHandling = options._unknownTypeHandling; _defaultBufferSize = options._defaultBufferSize; _maxDepth = options._maxDepth; _allowTrailingCommas = options._allowTrailingCommas; _ignoreNullValues = options._ignoreNullValues; _ignoreReadOnlyProperties = options._ignoreReadOnlyProperties; _ignoreReadonlyFields = options._ignoreReadonlyFields; _includeFields = options._includeFields; _propertyNameCaseInsensitive = options._propertyNameCaseInsensitive; _writeIndented = options._writeIndented; // Preserve backward compatibility with .NET 6 // This should almost certainly be changed, cf. https://github.com/dotnet/aspnetcore/issues/38720 _typeInfoResolver = options._typeInfoResolver is JsonSerializerContext ? null : options._typeInfoResolver; EffectiveMaxDepth = options.EffectiveMaxDepth; ReferenceHandlingStrategy = options.ReferenceHandlingStrategy; // _cachingContext is not copied as sharing the JsonTypeInfo and JsonPropertyInfo caches can result in // unnecessary references to type metadata, potentially hindering garbage collection on the source options. TrackOptionsInstance(this); }
public void Read_ObjectWithComments_ShouldMatch(JsonCommentHandling commentHandling) { const string json = @"/* Comment */{ /* Comment */ ""a"":1, // Comment ""b"": // Comment 2, /* Comment */ ""c"": /* Comment */ 3, ""d"": [ // Comment 4/* Comment */,/* Comment */ 5 /* Comment */ ]/* Comment */ /* Comment */}"; var jsonReaderOptions = new JsonReaderOptions { CommentHandling = commentHandling, }; var reader = new Utf8JsonReader(Encoding.UTF8.GetBytes(json).AsSpan(), jsonReaderOptions); reader.Read(); var converter = new ObjectConverter(); var actual = converter.Read(ref reader, typeof(object), new JsonSerializerOptions()); var expected = new Dictionary <string, object> { ["a"] = 1L, ["b"] = 2L, ["c"] = 3L, ["d"] = new List <object> { 4L, 5L }, }; JsonDeepEqualAssert.Equal(expected, actual); }
private static void SpanSequenceStatesAreEqualInvalidJson(byte[] dataUtf8, ReadOnlySequence <byte> sequence, int maxDepth, JsonCommentHandling commentHandling) { var stateSpan = new JsonReaderState(new JsonReaderOptions { CommentHandling = commentHandling, MaxDepth = maxDepth }); var jsonSpan = new Utf8JsonReader(dataUtf8, isFinalBlock: true, stateSpan); var stateSequence = new JsonReaderState(new JsonReaderOptions { CommentHandling = commentHandling, MaxDepth = maxDepth }); var jsonSequence = new Utf8JsonReader(sequence, isFinalBlock: true, stateSequence); try { while (true) { bool spanResult = jsonSpan.Read(); bool sequenceResult = jsonSequence.Read(); Assert.Equal(spanResult, sequenceResult); Assert.Equal(jsonSpan.CurrentDepth, jsonSequence.CurrentDepth); Assert.Equal(jsonSpan.BytesConsumed, jsonSequence.BytesConsumed); Assert.Equal(jsonSpan.TokenType, jsonSequence.TokenType); if (!spanResult) { break; } } Assert.True(false, "Expected JsonReaderException due to invalid JSON."); } catch (JsonReaderException) { } }
public override ClientRegisteredEvent Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) { JsonCommentHandling commentHandling = options.ReadCommentHandling; reader.SkipComments(commentHandling); reader.ExpectJsonToken(JsonTokenType.StartObject); Guid? eventId = null; string? clientIdentifier = null; ClientMetadata?info = null; IDictionary <string, FileMetadata>? addedFiles = null; IDictionary <string, FragmentMetadata>?addedFragments = null; while (reader.Read()) { if (reader.TokenType == JsonTokenType.Comment) { continue; } if (reader.TokenType == JsonTokenType.EndObject) { return(new ClientRegisteredEvent( clientIdentifier ?? throw new JsonException($"Property {nameof(ClientRegisteredEvent.ClientIdentifier)} is not defined."), info ?? throw new JsonException($"Property {nameof(ClientRegisteredEvent.Info)} is not defined."), addedFiles ?? throw new JsonException($"Property {nameof(ClientRegisteredEvent.AddedFiles)} is not defined."), addedFragments ?? throw new JsonException($"Property {nameof(ClientRegisteredEvent.AddedFragments)} is not defined."), eventId ?? throw new JsonException($"Property {nameof(ClientRegisteredEvent.EventId)} is not defined."))); } reader.ExpectJsonToken(JsonTokenType.PropertyName); string propertyName = reader.GetString(); if (propertyName.Equals(nameof(ClientRegisteredEvent.EventId))) { if (eventId.HasValue) { throw new JsonException("Property defined twice: " + propertyName); } reader.ReadSkippingComments(commentHandling); reader.ExpectJsonToken(JsonTokenType.String); eventId = reader.GetGuid(); } else if (propertyName.Equals(nameof(ClientRegisteredEvent.ClientIdentifier))) { if (clientIdentifier != null) { throw new JsonException("Property defined twice: " + propertyName); } reader.ReadSkippingComments(commentHandling); reader.ExpectJsonToken(JsonTokenType.String); clientIdentifier = reader.GetString(); } else if (propertyName.Equals(nameof(ClientRegisteredEvent.Info))) { if (!(info is null)) { throw new JsonException("Property defined twice: " + propertyName); } reader.ReadSkippingComments(commentHandling); reader.ExpectJsonToken(JsonTokenType.StartObject); info = JsonSerializer.Deserialize <ClientMetadata>(ref reader, options); } else if (propertyName.Equals(nameof(ClientRegisteredEvent.AddedFiles))) { if (!(addedFiles is null)) { throw new JsonException("Property defined twice: " + propertyName); } reader.ReadSkippingComments(commentHandling); reader.ExpectJsonToken(JsonTokenType.StartObject); addedFiles = JsonSerializer.Deserialize <IDictionary <string, FileMetadata> >(ref reader, options); } else if (propertyName.Equals(nameof(ClientRegisteredEvent.AddedFragments))) { if (!(addedFragments is null)) { throw new JsonException("Property defined twice: " + propertyName); } reader.ReadSkippingComments(commentHandling); reader.ExpectJsonToken(JsonTokenType.StartObject); addedFragments = JsonSerializer.Deserialize <IDictionary <string, FragmentMetadata> >(ref reader, options); } else { reader.Skip(); } } throw new JsonException("Json input ended unexpectedly."); }
public override FragmentDistributionEndedEvent Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) { JsonCommentHandling commentHandling = options.ReadCommentHandling; reader.SkipComments(commentHandling); reader.ExpectJsonToken(JsonTokenType.StartObject); Guid? eventId = null; string? hash = null; long? size = null; ISet <string>?receivers = null; while (reader.Read()) { if (reader.TokenType == JsonTokenType.Comment) { continue; } if (reader.TokenType == JsonTokenType.EndObject) { return(new FragmentDistributionEndedEvent( hash ?? throw new JsonException($"Property {nameof(FragmentDistributionEndedEvent.Hash)} is not defined."), size ?? throw new JsonException($"Property {nameof(FragmentDistributionEndedEvent.Size)} is not defined."), receivers ?? throw new JsonException($"Property {nameof(FragmentDistributionEndedEvent.Receivers)} is not defined."), eventId ?? throw new JsonException($"Property {nameof(FragmentDistributionEndedEvent.EventId)} is not defined."))); } reader.ExpectJsonToken(JsonTokenType.PropertyName); string propertyName = reader.GetString(); if (propertyName.Equals(nameof(FragmentDistributionEndedEvent.EventId))) { if (eventId.HasValue) { throw new JsonException("Property defined twice: " + propertyName); } reader.ReadSkippingComments(commentHandling); reader.ExpectJsonToken(JsonTokenType.String); eventId = reader.GetGuid(); } else if (propertyName.Equals(nameof(FragmentDistributionEndedEvent.Hash))) { if (!(hash is null)) { throw new JsonException("Property defined twice: " + propertyName); } reader.ReadSkippingComments(commentHandling); reader.ExpectJsonToken(JsonTokenType.String); hash = reader.GetString(); } else if (propertyName.Equals(nameof(FragmentDistributionEndedEvent.Size))) { if (size.HasValue) { throw new JsonException("Property defined twice: " + propertyName); } reader.ReadSkippingComments(commentHandling); reader.ExpectJsonToken(JsonTokenType.Number); size = reader.GetInt64(); } else if (propertyName.Equals(nameof(FragmentDistributionEndedEvent.Receivers))) { if (!(receivers is null)) { throw new JsonException("Property defined twice: " + propertyName); } reader.ReadSkippingComments(commentHandling); reader.ExpectJsonToken(JsonTokenType.StartArray); receivers = JsonSerializer.Deserialize <ISet <string> >(ref reader, options); } else { reader.Skip(); } } throw new JsonException("Json input ended unexpectedly."); }
public override ClientJoinAcceptedEvent Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) { JsonCommentHandling commentHandling = options.ReadCommentHandling; reader.SkipComments(commentHandling); reader.ExpectJsonToken(JsonTokenType.StartObject); Guid? eventId = null; string?clientIdentifier = null; long? fragmentSize = null; IDictionary <string, FileMetadata>? addFileInfos = null; IDictionary <string, FragmentMetadata>?addFragmentInfos = null; ISet <string>?removeFileInfos = null; ISet <string>?removeFragments = null; IDictionary <string, ClientMetadata>?clients = null; while (reader.Read()) { if (reader.TokenType == JsonTokenType.Comment) { continue; } if (reader.TokenType == JsonTokenType.EndObject) { return(new ClientJoinAcceptedEvent( eventId: eventId ?? throw new JsonException($"Property {nameof(ClientJoinAcceptedEvent.EventId)} is not defined."), clientIdentifier: clientIdentifier ?? throw new JsonException($"Property {nameof(ClientJoinAcceptedEvent.ClientIdentifier)} is not defined."), fragmentSize: fragmentSize ?? throw new JsonException($"Property {nameof(ClientJoinAcceptedEvent.FragmentSize)} is not defined."), addFileInfos: addFileInfos ?? throw new JsonException($"Property {nameof(ClientJoinAcceptedEvent.AddFileInfos)} is not defined."), addFragmentInfos: addFragmentInfos ?? throw new JsonException($"Property {nameof(ClientJoinAcceptedEvent.AddFragmentInfos)} is not defined."), removeFileInfos: removeFileInfos ?? throw new JsonException($"Property {nameof(ClientJoinAcceptedEvent.RemoveFileInfos)} is not defined."), removeFragmentInfos: removeFragments ?? throw new JsonException($"Property {nameof(ClientJoinAcceptedEvent.RemoveFragmentInfos)} is not defined."), clients: clients ?? throw new JsonException($"Property {nameof(ClientJoinAcceptedEvent.Clients)} is not defined."))); } reader.ExpectJsonToken(JsonTokenType.PropertyName); string propertyName = reader.GetString(); if (propertyName.Equals(nameof(ClientJoinAcceptedEvent.EventId))) { if (eventId.HasValue) { throw new JsonException("Property defined twice: " + propertyName); } reader.ReadSkippingComments(commentHandling); reader.ExpectJsonToken(JsonTokenType.String); eventId = reader.GetGuid(); } else if (propertyName.Equals(nameof(ClientJoinAcceptedEvent.ClientIdentifier))) { if (!(clientIdentifier is null)) { throw new JsonException("Property defined twice: " + propertyName); } reader.ReadSkippingComments(commentHandling); reader.ExpectJsonToken(JsonTokenType.String); clientIdentifier = reader.GetString(); } else if (propertyName.Equals(nameof(ClientJoinAcceptedEvent.FragmentSize))) { if (fragmentSize.HasValue) { throw new JsonException("Property defined twice: " + propertyName); } reader.ReadSkippingComments(commentHandling); reader.ExpectJsonToken(JsonTokenType.Number); fragmentSize = reader.GetInt64(); } else if (propertyName.Equals(nameof(ClientJoinAcceptedEvent.AddFileInfos))) { if (!(addFileInfos is null)) { throw new JsonException("Property defined twice: " + propertyName); } reader.ReadSkippingComments(commentHandling); reader.ExpectJsonToken(JsonTokenType.StartObject); addFileInfos = JsonSerializer.Deserialize <IDictionary <string, FileMetadata> >(ref reader, options); } else if (propertyName.Equals(nameof(ClientJoinAcceptedEvent.AddFragmentInfos))) { if (addFragmentInfos != null) { throw new JsonException("Property defined twice: " + propertyName); } reader.ReadSkippingComments(commentHandling); reader.ExpectJsonToken(JsonTokenType.StartObject); addFragmentInfos = JsonSerializer.Deserialize <IDictionary <string, FragmentMetadata> >(ref reader, options); } else if (propertyName.Equals(nameof(ClientJoinAcceptedEvent.RemoveFileInfos))) { if (!(removeFileInfos is null)) { throw new JsonException("Property defined twice: " + propertyName); } reader.ReadSkippingComments(commentHandling); reader.ExpectJsonToken(JsonTokenType.StartArray); removeFileInfos = JsonSerializer.Deserialize <ISet <string> >(ref reader, options); } else if (propertyName.Equals(nameof(ClientJoinAcceptedEvent.RemoveFragmentInfos))) { if (!(removeFragments is null)) { throw new JsonException("Property defined twice: " + propertyName); } reader.ReadSkippingComments(commentHandling); reader.ExpectJsonToken(JsonTokenType.StartArray); removeFragments = JsonSerializer.Deserialize <ISet <string> >(ref reader, options); } else if (propertyName.Equals(nameof(ClientJoinAcceptedEvent.Clients))) { if (!(clients is null)) { throw new JsonException("Property defined twice: " + propertyName); } reader.ReadSkippingComments(commentHandling); reader.ExpectJsonToken(JsonTokenType.StartObject); clients = JsonSerializer.Deserialize <IDictionary <string, ClientMetadata> >(ref reader, options); } else { reader.Skip(); } } throw new JsonException("Json input ended unexpectedly."); }
public override ClientJoinRequestedEvent Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) { JsonCommentHandling commentHandling = options.ReadCommentHandling; reader.SkipComments(commentHandling); reader.ExpectJsonToken(JsonTokenType.StartObject); bool readFragmentSize = false; Guid? eventId = null; string?hashAlgorithm = null; long? fragmentSize = null; IDictionary <string, FileMetadata>? knownFileInfos = null; IDictionary <string, FragmentMetadata>?storedFragments = null; ISet <Uri>?endpoints = null; while (reader.Read()) { if (reader.TokenType == JsonTokenType.Comment) { continue; } if (reader.TokenType == JsonTokenType.EndObject) { return(new ClientJoinRequestedEvent( knownFileInfos ?? throw new JsonException($"Property {nameof(ClientJoinRequestedEvent.KnownFileInfos)} is not defined."), storedFragments ?? throw new JsonException($"Property {nameof(ClientJoinRequestedEvent.StoredFragments)} is not defined."), endpoints ?? throw new JsonException($"Property {nameof(ClientJoinRequestedEvent.Endpoints)} is not defined."), hashAlgorithm ?? throw new JsonException($"Property {nameof(ClientJoinRequestedEvent.HashAlgorithm)} is not defined."), fragmentSize, eventId ?? throw new JsonException($"Property {nameof(ClientJoinRequestedEvent.EventId)} is not defined."))); } reader.ExpectJsonToken(JsonTokenType.PropertyName); string propertyName = reader.GetString(); if (propertyName.Equals(nameof(ClientJoinRequestedEvent.EventId))) { if (eventId.HasValue) { throw new JsonException("Property defined twice: " + propertyName); } reader.ReadSkippingComments(commentHandling); reader.ExpectJsonToken(JsonTokenType.String); eventId = reader.GetGuid(); } else if (propertyName.Equals(nameof(ClientJoinRequestedEvent.HashAlgorithm))) { if (!(hashAlgorithm is null)) { throw new JsonException("Property defined twice: " + propertyName); } reader.ReadSkippingComments(commentHandling); reader.ExpectJsonToken(JsonTokenType.String); hashAlgorithm = reader.GetString(); } else if (propertyName.Equals(nameof(ClientJoinRequestedEvent.FragmentSize))) { if (readFragmentSize) { throw new JsonException("Property defined twice: " + propertyName); } readFragmentSize = true; reader.ReadSkippingComments(commentHandling); fragmentSize = reader.TokenType switch { JsonTokenType.Number => new long?(reader.GetInt64()), JsonTokenType.Null => null, _ => throw new JsonException($"Expected Token Type Number or Null. Actual: {reader.TokenType}") }; } else if (propertyName.Equals(nameof(ClientJoinRequestedEvent.KnownFileInfos))) { if (!(knownFileInfos is null)) { throw new JsonException("Property defined twice: " + propertyName); } reader.ReadSkippingComments(commentHandling); reader.ExpectJsonToken(JsonTokenType.StartObject); knownFileInfos = JsonSerializer.Deserialize <IDictionary <string, FileMetadata> >(ref reader, options); } else if (propertyName.Equals(nameof(ClientJoinRequestedEvent.StoredFragments))) { if (!(storedFragments is null)) { throw new JsonException("Property defined twice: " + propertyName); } reader.ReadSkippingComments(commentHandling); reader.ExpectJsonToken(JsonTokenType.StartObject); storedFragments = JsonSerializer.Deserialize <IDictionary <string, FragmentMetadata> >(ref reader, options); } else if (propertyName.Equals(nameof(ClientJoinRequestedEvent.Endpoints))) { if (!(endpoints is null)) { throw new JsonException("Property defined twice: " + propertyName); } reader.ReadSkippingComments(commentHandling); reader.ExpectJsonToken(JsonTokenType.StartArray); endpoints = JsonSerializer.Deserialize <ISet <Uri> >(ref reader, options); } else { reader.Skip(); } } throw new JsonException("Json input ended unexpectedly."); }
public static object ReturnObjectHelper(byte[] data, JsonCommentHandling commentHandling = JsonCommentHandling.Disallow) { var state = new JsonReaderState(options: new JsonReaderOptions { CommentHandling = commentHandling }); var reader = new Utf8JsonReader(data, true, state); return ReaderLoop(ref reader); }
public static byte[] ReturnBytesHelper(byte[] data, out int length, JsonCommentHandling commentHandling = JsonCommentHandling.Disallow, int maxDepth = 64) { var state = new JsonReaderState(new JsonReaderOptions { CommentHandling = commentHandling, MaxDepth = maxDepth }); var reader = new Utf8JsonReader(data, true, state); return ReaderLoop(data.Length, out length, ref reader); }
public override ClientJoinDeniedEvent Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) { JsonCommentHandling commentHandling = options.ReadCommentHandling; reader.SkipComments(commentHandling); reader.ExpectJsonToken(JsonTokenType.StartObject); bool readReason = false; Guid? eventId = null; string?clientIdentifier = null; ClientJoinDeniedCode?reasonCode = null; string?reason = null; while (reader.Read()) { if (reader.TokenType == JsonTokenType.Comment) { continue; } if (reader.TokenType == JsonTokenType.EndObject) { return(new ClientJoinDeniedEvent( eventId: eventId ?? throw new JsonException($"Property {nameof(ClientJoinAcceptedEvent.EventId)} is not defined."), clientIdentifier: clientIdentifier ?? throw new JsonException($"Property {nameof(ClientJoinAcceptedEvent.ClientIdentifier)} is not defined."), reasonCode: reasonCode ?? throw new JsonException($"Property {nameof(ClientJoinAcceptedEvent.ClientIdentifier)} is not defined."), reason: reason)); } reader.ExpectJsonToken(JsonTokenType.PropertyName); string propertyName = reader.GetString(); if (propertyName.Equals(nameof(ClientJoinDeniedEvent.EventId))) { if (eventId.HasValue) { throw new JsonException("Property defined twice: " + propertyName); } reader.ReadSkippingComments(commentHandling); reader.ExpectJsonToken(JsonTokenType.String); eventId = reader.GetGuid(); } else if (propertyName.Equals(nameof(ClientJoinDeniedEvent.ClientIdentifier))) { if (!(clientIdentifier is null)) { throw new JsonException("Property defined twice: " + propertyName); } reader.ReadSkippingComments(commentHandling); reader.ExpectJsonToken(JsonTokenType.String); clientIdentifier = reader.GetString(); } else if (propertyName.Equals(nameof(ClientJoinDeniedEvent.ReasonCode))) { if (reasonCode.HasValue) { throw new JsonException("Property defined twice: " + propertyName); } reader.ReadSkippingComments(commentHandling); reader.ExpectJsonToken(JsonTokenType.Number); reasonCode = (ClientJoinDeniedCode)reader.GetInt32(); if (!Enum.IsDefined(typeof(ClientJoinDeniedCode), reasonCode.Value)) { throw new JsonException(reasonCode.Value + " is an invalid enum value of " + nameof(ClientJoinDeniedCode)); } } else if (propertyName.Equals(nameof(ClientJoinDeniedEvent.Reason))) { if (readReason) { throw new JsonException("Property defined twice: " + propertyName); } readReason = true; reader.ReadSkippingComments(commentHandling); reason = reader.TokenType switch { JsonTokenType.String => reader.GetString(), JsonTokenType.Null => null, _ => throw new JsonException($"Expected Token Type String or Null. Actual: {reader.TokenType}") }; } else { reader.Skip(); } } throw new JsonException("Json input ended unexpectedly."); }