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
TThe 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
readerUtf8JsonReaderThe Utf8JsonReader to read from.
typeToConvertTypeThe type to convert.
optionsJsonSerializerOptionsThe serializer options to use.
Returns
- T
The converted value object of type
T.
Remarks
This method:
- Reads the JSON string value using GetString()
- Delegates to
T's Parse(string, IFormatProvider) method - Throws JsonException if parsing fails
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
writerUtf8JsonWriterThe Utf8JsonWriter to write to.
valueTThe value object to convert to JSON.
optionsJsonSerializerOptionsThe 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.).