Table of Contents

Class ParsableJsonConverter<T>

Namespace
FunctionalDdd
Assembly
FunctionalDdd.CommonValueObjects.dll

A JSON converter for value objects that implement IParsable<TSelf>. Enables automatic serialization and deserialization of parsable value objects in ASP.NET Core APIs and System.Text.Json scenarios.

public class ParsableJsonConverter<T> : JsonConverter<T> where T : IParsable<T>

Type Parameters

T

The type of the value object to convert. Must implement IParsable<TSelf>.

Inheritance
ParsableJsonConverter<T>
Inherited Members
Extension Methods

Examples

Applying the converter to a value object:

[JsonConverter(typeof(ParsableJsonConverter<EmailAddress>))]
public partial class EmailAddress : ScalarValueObject<string>, IParsable<EmailAddress>
{
    private EmailAddress(string value) : base(value) { }

    public static EmailAddress Parse(string s, IFormatProvider? provider)
    {
        var result = TryCreate(s);
        if (result.IsFailure)
            throw new FormatException("Invalid email address");
        return result.Value;
    }

    public static bool TryParse(string? s, IFormatProvider? provider, 
        out EmailAddress result)
    {
        var r = TryCreate(s);
        result = r.IsSuccess ? r.Value : default!;
        return r.IsSuccess;
    }

    public override string ToString() => Value;
}

Automatic JSON serialization in DTOs:

public record UserDto(
    UserId Id,
    EmailAddress Email,
    FirstName FirstName
);

var user = new UserDto(
    UserId.NewUnique(),
    EmailAddress.TryCreate("user@example.com").Value,
    FirstName.TryCreate("John").Value
);

var json = JsonSerializer.Serialize(user);
// Produces:
// {
//   "id": "550e8400-e29b-41d4-a716-446655440000",
//   "email": "user@example.com",
//   "firstName": "John"
// }

var deserialized = JsonSerializer.Deserialize<UserDto>(json);
// Automatically parses strings back to value objects

Using in API endpoints:

public record CreateUserRequest(
    EmailAddress Email,
    FirstName FirstName,
    LastName LastName
);

// Minimal API
app.MapPost("/users", (CreateUserRequest request) =>
{
    // Value objects are already parsed and validated from JSON
    return _userService.CreateUser(request.Email, request.FirstName, request.LastName)
        .ToHttpResult();
});

// MVC Controller
[HttpPost]
public ActionResult<UserDto> CreateUser(CreateUserRequest request)
{
    // ASP.NET Core automatically deserializes JSON strings to value objects
    return _userService.CreateUser(request.Email, request.FirstName, request.LastName)
        .ToActionResult(this);
}

// JSON Request:
// {
//   "email": "user@example.com",
//   "firstName": "John",
//   "lastName": "Doe"
// }

Error handling during deserialization:

// Invalid JSON value throws JsonException during deserialization
var invalidJson = @"{""email"": ""not-a-valid-email""}";

try
{
    var dto = JsonSerializer.Deserialize<UserDto>(invalidJson);
}
catch (JsonException ex)
{
    // Exception message contains the FormatException from EmailAddress.Parse
    Console.WriteLine($"JSON deserialization failed: {ex.Message}");
}

// In ASP.NET Core, this automatically becomes a 400 Bad Request
// with model validation error details

Remarks

This converter provides seamless JSON integration for value objects by:

  • Serializing value objects to their string representation
  • Deserializing JSON strings back to value objects using the Parse method
  • Maintaining type safety throughout the serialization process
  • Working with ASP.NET Core model binding and validation

The converter delegates to the value object's Parse(string, IFormatProvider) and ToString() methods, ensuring consistent behavior between JSON serialization and other parsing scenarios.

Common usage:

  • Applied via [JsonConverter] attribute on value object classes
  • Enables clean JSON APIs without manual conversion code
  • Supports both request deserialization and response serialization
  • Works with minimal APIs, MVC controllers, and HttpClient

Methods

Read(ref Utf8JsonReader, Type, JsonSerializerOptions)

Reads and converts the JSON to type T.

public override T? Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)

Parameters

reader Utf8JsonReader

The Utf8JsonReader to read from.

typeToConvert Type

The type to convert.

options JsonSerializerOptions

The serializer options to use.

Returns

T

The converted value object of type T.

Remarks

This method:

In ASP.NET Core, deserialization failures are automatically handled and converted to 400 Bad Request responses with appropriate error messages.

Exceptions

JsonException

Thrown when the JSON value cannot be parsed into a valid value object. The inner exception contains the FormatException from the value object's Parse method.

Write(Utf8JsonWriter, T, JsonSerializerOptions)

Writes a specified value as JSON.

public override void Write(Utf8JsonWriter writer, T value, JsonSerializerOptions options)

Parameters

writer Utf8JsonWriter

The Utf8JsonWriter to write to.

value T

The value object to convert to JSON.

options JsonSerializerOptions

The serializer options to use.

Remarks

This method converts the value object to its string representation using ToString() and writes it as a JSON string value.

For value objects inheriting from ScalarValueObject<T>, this typically returns the wrapped primitive value (e.g., the email string, GUID string, etc.).

See Also