Replace JSON.NET with System.Text.Json 10.x#359
Open
niemyjski wants to merge 4 commits into
Open
Conversation
- Remove vendored Newtonsoft.Json (entire src/Exceptionless/Newtonsoft.Json/ directory) - Remove update-json.ps1 script - Add System.Text.Json 10.0.0 NuGet package reference - Rewrite DefaultJsonSerializer using System.Text.Json with: - SnakeCaseNamingPolicy matching legacy Newtonsoft behavior (e.g. OSName -> o_s_name) - Per-type snake_case applied only to Exceptionless.Models namespace - DataDictionaryConverter for storing complex values as JSON strings - SettingsDictionaryConverter for ObservableDictionary-based type - ObjectToInferredTypesConverter for proper type inference - PostDataConverter to convert object/array PostData to indented strings - Custom WriteValue with depth limiting and property exclusion support - Update all model classes to remove [JsonObject] attributes - Add [JsonPropertyName] for EnvironmentInfo OS properties - Update DefaultSubmissionClient to use JsonDocument instead of JObject - All 300 tests pass Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…sion bug - Replace custom SnakeCaseNamingPolicy with built-in JsonNamingPolicy.SnakeCaseLower (aligns with server approach in exceptionless/Exceptionless#2135) - Delete unused SnakeCaseNamingPolicy.cs - Fix DataDictionaryConverter.Write: use WriteRawValue for JSON strings that were previously objects (fixes double-escaping on storage roundtrip) - Fix exclusion logic: add TypeInfoResolver = new DefaultJsonTypeInfoResolver() so GetTypeInfo() works and WriteValue can filter properties by name - Update all test assertions to expect snake_case property names Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
WriteValue for IDictionary entries wrote the property name before checking whether the value could actually be serialized at the current depth. When a complex value exceeded maxDepth, WriteValue returned without writing anything, leaving the JSON writer in an invalid state. The error was silently swallowed by continueOnSerializationError, causing a fallback to full serialization (effectively ignoring the depth limit entirely). Fix: check depth before writing the property name. Skip complex dictionary entries that would exceed maxDepth, consistent with the object property path. Added regression test that fails before the fix (depth limit violated) and passes after. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- preserve literal JSON-looking strings in DataDictionary as strings - restore raw JSON emission only for values produced from structured data - preserve raw JSON markers through MessagePack storage roundtrips - coerce primitive SettingsDictionary JSON values to strings like main - keep dictionary depth-limit regression coverage Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Drops Newtonsoft.Json (JSON.NET) entirely from the Exceptionless .NET client and replaces it with System.Text.Json 10.x.
Key Changes
Serializer Infrastructure
src/Exceptionless/Newtonsoft.Json/directory (hundreds of files)DefaultJsonSerializerusing STJ withJsonNamingPolicy.SnakeCaseLower(matches server approach from Replace JSON.NET with System.Text.Json across the codebase Exceptionless#2135)DataDictionaryConverterfor the specialDataDictionarytype (stores complex values as raw JSON strings)SettingsDictionaryConverterfor theSettingsDictionarytypePostDataConverterforRequestInfo.PostData(object → indented string on deserialization)Bug Fixes
DataDictionary roundtrip bug (CRITICAL): When events go through storage (serialize → deserialize → re-serialize for API), complex objects in
Event.Databecame escaped strings instead of JSON objects. Fixed by usingWriteRawValuefor string values that start with{or[.Exclusion logic bug:
GetTypeInfo()silently threw without an explicitTypeInfoResolver, causing theWriteValueexclusion/depth logic to fall through to direct serialization. Fixed by addingTypeInfoResolver = new DefaultJsonTypeInfoResolver().Wire Format Alignment
JsonNamingPolicy.SnakeCaseLowerglobally (same as server)[JsonPropertyName]attributes onEnvironmentInfo.OSName/OSVersionfor legacyo_s_name/o_s_versionformatPropertyNameCaseInsensitive = truefor flexible deserializationDependencies
System.Text.Json10.0.0-preview.4.25258.110 (supports netstandard2.0)Testing