Skip to content

Conversation

@niemyjski
Copy link
Member

This is a WIP, it's really close but some serialization stuff needs to be refactored and cleaned up, mainly the websocket manager.

@niemyjski niemyjski self-assigned this Dec 6, 2025
@niemyjski niemyjski requested a review from ejsmith December 6, 2025 03:20
@niemyjski niemyjski force-pushed the feature/scalar-system-text-json branch from 612abcd to f6a5805 Compare December 6, 2025 03:25
@niemyjski niemyjski force-pushed the feature/scalar-system-text-json branch from f6a5805 to 24bd01b Compare January 12, 2026 03:58
Comment on lines +113 to +122
foreach (var propertyName in value.GetChangedPropertyNames())
{
if (value.TryGetPropertyValue(propertyName, out var propertyValue))
{
// Convert property name to snake_case if needed
var jsonPropertyName = options.PropertyNamingPolicy?.ConvertName(propertyName) ?? propertyName;
writer.WritePropertyName(jsonPropertyName);
JsonSerializer.Serialize(writer, propertyValue, _options);
}
}
Removes duplicate package references and cleans up unused package references in the Exceptionless.Web project file.
This ensures that the project has a consistent and minimal set of dependencies.
Removes the DeltaOperationFilter as it is no longer needed.
Updates the Scalar.AspNetCore package to the latest version.

This change also updates the Scalar configuration to support
multiple API documentation versions and includes updates to the
route pattern and authentication.
Updates documentation configuration to streamline access and improve security.

Redirects the `/docs/index.html` path to `/docs` for a cleaner user experience.

Simplifies the API key authentication scheme in the documentation, replacing username/password and token authentication. The key is renamed to "Token" and the security scheme is updated to "Bearer". This change provides a more straightforward and modern approach to API authentication documentation.
Migrates WebSocket message serialization to use System.Text.Json with a lower-case underscore naming policy.

This change ensures consistent serialization behavior across the application, improving maintainability and reducing potential issues related to different JSON serialization libraries.
The naming policy enforces a standard for property names in serialized JSON, enhancing data exchange between client and server.
Configures System.Text.Json serializer options in the test suite
to use the custom naming policy and delta converter. This ensures
consistent serialization behavior in tests.
Updates authentication models to remove the `required` keyword.
This change ensures that null values can be handled correctly,
aligning with the desired behavior when using System.Text.Json.

dotnet/runtime#110733 (comment)
dotnet/aspnetcore#61511 (comment)
Converts the project to use System.Text.Json for serialization, replacing Newtonsoft.Json where possible.

This change aims to improve performance and reduce dependencies by leveraging the built-in System.Text.Json library.

Configures Newtonsoft.Json for some legacy usages.
Configures the JsonSerializerOptions to ignore null values when writing JSON.

This prevents unnecessary null values from being included in the serialized output, resulting in more concise and efficient data transfer.
Adds a converter to handle deserialization of object properties to inferred types, enabling correct interpretation of different value types.

This change also ensures that the TypeDescriptor converter is correctly retrieved before checking if it can perform the conversion.
Improves the `DataDictionary` extension methods to handle various JSON types, including `JsonDocument`, `JsonElement`, `JsonNode`, dictionaries, and lists, using System.Text.Json.

This change ensures proper deserialization and type conversion of values stored in the dictionary, especially when data originates from different sources or serialization methods. It also updates event processing and formatting plugins to utilize JsonSerializerOptions for data retrieval.

Addresses Elasticsearch compatibility by handling JObjects. Adds a new `ObjectToInferredTypesConverter` to deserialize object properties into appropriate .NET types.
This commit refactors the EventExtensions class to accept JsonSerializerOptions.

Previously, certain methods in EventExtensions that retrieved data from an Event's Data property lacked a JsonSerializerOptions parameter, potentially leading to issues with deserialization when custom options were required.

Now, these methods accept a JsonSerializerOptions parameter, and a try-catch block has been added to handle potential deserialization exceptions. This change ensures that the correct JsonSerializerOptions are used when deserializing data from the event and enhances the robustness of the code by gracefully handling deserialization errors.
Improves OpenAPI schema generation by:

- Applying schema transformers to handle Delta types, read-only properties, unique items, and enum names correctly.
- Removing Problem JSON content type from successful responses.
- Adding support for request body content attributes.
- Utilizing XML documentation for operation descriptions.

These changes ensure accurate and comprehensive API documentation.
Comment on lines +33 to +42
foreach (var property in innerType.GetProperties(BindingFlags.Public | BindingFlags.Instance))
{
if (!property.CanRead || !property.CanWrite)
continue;

var propertySchema = CreateSchemaForType(property.PropertyType);
string propertyName = property.Name.ToLowerUnderscoredWords();

schema.Properties[propertyName] = propertySchema;
}
Comment on lines +22 to +34
foreach (var property in type.GetProperties())
{
if (!property.CanRead || property.CanWrite)
continue;

// Find the matching schema property (property names are in snake_case in the schema)
string schemaPropertyName = property.Name.ToLowerUnderscoredWords();
if (schema.Properties.TryGetValue(schemaPropertyName, out var propertySchema) && propertySchema is OpenApiSchema mutableSchema)
{
// Cast to OpenApiSchema to access mutable properties
mutableSchema.ReadOnly = true;
}
}
Comment on lines +16 to +26
foreach (var operations in document.Paths.Select(p => p.Value.Operations))
{
if (operations is null)
continue;

foreach (var response in operations.Values.SelectMany(v => v.Responses ?? []).Where(r => r.Key.StartsWith('2') && r.Value.Content is not null))
{
// Only process 2xx success responses
response.Value.Content?.Remove(ProblemJsonContentType);
}
}
Improves number deserialization within the custom JSON converter
by prioritizing smaller integer types (int) and decimal before
falling back to larger types (long, double). This aims to improve
boxing efficiency and precision when handling numeric values. It also
adds DateTime support.
Updates Foundatio packages to beta1.7.

Updates Scalar.AspNetCore package to 2.12.13.
Updates formatting plugins to utilize System.Text.Json for event data serialization and deserialization.

This change ensures consistency across the application by using a single JSON library.
Removes the ITextSerializer contract tests as these are no longer needed.

The purpose of these tests were to ensure that all serialization methods work correctly and consistently, and that the serializer can be swapped without breaking functionality.
Since the system text json serializer does not implement Foundatio.Serializer.ITextSerializer and the new code directly uses System.Text.Json this abstraction is no longer useful.
This commit updates the serializer to correctly infer types, specifically changing integer type inference from `long` to `int` and ensuring decimal types are inferred as `decimal`.

It also replaces `Assert.Contains` with `Assert.Equal` for JSON serialization tests, ensuring exact matching and improves test readability with language injection.
Updates tests and JSON deserialization logic to correctly
handle decimal values. It ensures that decimal types and values
are properly preserved during deserialization, preventing
potential data loss or incorrect interpretations.
Updates the Scalar.AspNetCore package version to the latest release.
This ensures compatibility and incorporates the latest features and bug fixes.
Adds descriptions for Basic, Bearer, and Token authentication schemes to the OpenAPI documentation. This provides users with more information on how to authenticate with the API.
Assert.NotNull(deserialized?.PostData);
var postData = deserialized.PostData as IDictionary<string, object>;
Assert.NotNull(postData);
Assert.Equal("testuser", postData["username"]);
string? postData = deserialized.PostData.ToString();
Assert.Contains("testuser", postData);
Assert.NotNull(deserialized?.PostData);
var postData = deserialized.PostData as IDictionary<string, object>;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Development

Successfully merging this pull request may close these issues.

2 participants