PR #4: Migrate: Newtonsoft.Json -> System.Text.Json#97
Open
AlexanderJohnston wants to merge 37 commits into
Open
PR #4: Migrate: Newtonsoft.Json -> System.Text.Json#97AlexanderJohnston wants to merge 37 commits into
AlexanderJohnston wants to merge 37 commits into
Conversation
- Write to the client stream whether or not the checkpoint write succeeds - Do not ignore events routed to stopped flows - Avoid a null reference when an existing flow fails to load
The SkipException handling that required await was removed in a prior commit. Simplify back to returning the task directly. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Feature/dotnet10 upgrade
Feature/grpc cleanup
Transition core standard libraries to net10.
- Upgrade Totem, Totem.Runtime, Totem.Timeline, Totem.App.Tests from netstandard2.0 to net10.0 - Update Microsoft.Extensions.* package versions from 2.2.0 to 10.0.0 - Replace FormatterServices.GetUninitializedObject() with RuntimeHelpers.GetUninitializedObject() in DurableType.cs - Replace Assembly.LoadWithPartialName() with Assembly.Load(new AssemblyName()) in TypeResolver.cs - Remove ToHashSet extension methods that conflict with built-in LINQ on net10.0 - Fix C# 14 field keyword conflict in Fields.cs Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Create new STJ infrastructure replacing Newtonsoft.Json core: - Add TotemJsonTypeInfoResolver: replaces JsonFormatContractResolver and JsonFormatSerializationBinder with DefaultJsonTypeInfoResolver + Modifiers - Many<T> collection creation via expression-compiled factory - Durable type object creation via RuntimeHelpers.GetUninitializedObject() - Property filtering: excludes [Transient], [CompilerGenerated], Notion-declared - Private field/property serialization for durable types - [WriteOnly] attribute support (serialize but don't deserialize) - Add DurableTypeDiscriminatorConverter: JsonConverterFactory handling polymorphic \ property with 'durable:Prefix:TypeName' values for backward compatibility with Newtonsoft-serialized EventStore data. Includes TypeResolver fallback for legacy assembly-qualified type names. - Redesign IJsonFormat: expose JsonSerializerOptions instead of Apply() pattern - Rewrite JsonFormat: simple wrapper around JsonSerializerOptions - Rewrite JsonFormatExtensions: use JsonSerializer/JsonNode instead of JsonConvert/JObject. Add ToJsonNode/ToJsonNodeUtf8 methods replacing JObject. Implement CopyProperties for PopulateObject equivalent. - Rewrite JsonFormatOptions: SerializerOptions replaces SerializerSettings - Rewrite JsonFormatOptionsSetup: configure WriteIndented, CamelCase naming, JsonStringEnumConverter, TotemJsonTypeInfoResolver, DurableTypeDiscriminatorConverter - Update JsonServiceExtensions: use SerializerOptions Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
… STJ Phase 3 - Timeline Converters: - Rewrite FlowKeyConverter as JsonConverter<FlowKey> using Utf8JsonReader/Writer - Rewrite TimelinePositionConverter as JsonConverter<TimelinePosition> - Update TimelineJsonFormatOptionsSetup to use SerializerOptions Phase 4 - EventStore Layer: - Rewrite SubscribeCommand: replace JObject/JArray/JToken (Newtonsoft.Json.Linq) with JsonNode/JsonArray (System.Text.Json.Nodes) - Use JsonNode.GetValue<T>() instead of JToken.Value<T>() - Use JsonArray instead of JArray, pattern matching with 'is JsonArray' Phase 5 - MVC Layer: - Rewrite WebRuntimeOptionsSetup: replace IPostConfigureOptions<MvcNewtonsoftJsonOptions> with IPostConfigureOptions<JsonOptions>, copying STJ settings instead of 22 Newtonsoft properties - Remove .AddNewtonsoftJson() from ConfigureWebApp.cs (STJ is MVC default) Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…iles - Remove Newtonsoft.Json 13.0.3 package from Totem.Runtime.csproj - Remove Microsoft.AspNetCore.Mvc.NewtonsoftJson 10.0.0 package from Totem.Timeline.Mvc.csproj - Delete JsonFormatContractResolver.cs (replaced by TotemJsonTypeInfoResolver) - Delete JsonFormatSerializationBinder.cs (merged into DurableTypeDiscriminatorConverter) All direct Newtonsoft.Json dependencies are now removed. The only remaining Newtonsoft reference is a transitive dependency from EventStore.Client.Grpc (Newtonsoft.Json 9.0.1) which is outside our control. Solution builds with 0 errors across all projects. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
The DurableTypeDiscriminatorConverter.Read method was only checking the first property for the \ discriminator. Since JSON property order is not guaranteed, this could miss the discriminator and deserialize as the base type instead of the actual polymorphic type. Now scans through all properties using Utf8JsonReader.TrySkip() to find \ regardless of position in the JSON object. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…o STJ STJ does not auto-detect [TypeConverter] attributes like Newtonsoft did. This caused deserialization crashes for 20+ types (TypeName, Id, FileLink, etc.) that use TextConverter for string-based serialization. The factory detects types with a non-default TypeConverter that supports string conversion, and serializes/deserializes them as JSON strings via ConvertFromInvariantString/ConvertToInvariantString. Registered in JsonFormatOptionsSetup.Configure() after JsonStringEnumConverter, before the durable type converters in PostConfigure(). No conflicts since TypeConverter types are not durable. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…ctory Add TypeConverterJsonConverterFactory to bridge [TypeConverter] types to STJ
…only The previous check matched all .NET built-in types with TypeConverters (int, DateTime, bool, Guid, etc.), causing reader.GetString() to throw on non-string JSON tokens. This silently broke ASP.NET model binding for any model with non-string properties (e.g. SmartScanRecord.FileCount). Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Narrow TypeConverterJsonConverterFactory and add dictionary key support
| // Details | ||
| // | ||
|
|
||
| static void CopyProperties(object source, object target, Type type) |
Author
There was a problem hiding this comment.
Sanity check this later.
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.
This PR completes the migration from Newtonsoft.Json to System.Text.Json (STJ) across the entire Totem framework.
Changes
Phase 1: Upgrade TFMs to net10.0 and modernize obsolete APIs
Phase 2: Core System.Text.Json implementation
Phase 3–5: Migrate Timeline, EventStore, and MVC layers
Phase 6: Remove Newtonsoft.Json dependencies
TypeConverter bridge
Summary