ModelingEvolution.JsonParsableConverter
1.0.0
dotnet add package ModelingEvolution.JsonParsableConverter --version 1.0.0
NuGet\Install-Package ModelingEvolution.JsonParsableConverter -Version 1.0.0
<PackageReference Include="ModelingEvolution.JsonParsableConverter" Version="1.0.0" />
<PackageVersion Include="ModelingEvolution.JsonParsableConverter" Version="1.0.0" />
<PackageReference Include="ModelingEvolution.JsonParsableConverter" />
paket add ModelingEvolution.JsonParsableConverter --version 1.0.0
#r "nuget: ModelingEvolution.JsonParsableConverter, 1.0.0"
#:package ModelingEvolution.JsonParsableConverter@1.0.0
#addin nuget:?package=ModelingEvolution.JsonParsableConverter&version=1.0.0
#tool nuget:?package=ModelingEvolution.JsonParsableConverter&version=1.0.0
JsonParsableConverter
A high-performance System.Text.Json converter for types implementing IParsable<T>
. This library enables seamless JSON serialization/deserialization for custom value types, records, and structs using the standard .NET IParsable
pattern.
Features
- 🚀 High Performance: Leverages System.Text.Json for optimal performance
- 🎯 Type Safe: Full compile-time type safety with generic constraints
- 🔧 Easy Integration: Simple registration with JsonSerializerOptions
- 📦 Minimal Dependencies: Only depends on System.Text.Json
- 🧩 DDD Friendly: Perfect for Domain-Driven Design value objects and strongly-typed IDs
Installation
dotnet add package ModelingEvolution.JsonParsableConverter
Quick Start
Define a Parsable Type
using System.Text.Json.Serialization;
using ModelingEvolution.JsonParsableConverter;
[JsonConverter(typeof(JsonParsableConverter<ProductId>))]
public readonly record struct ProductId(Guid Value) : IParsable<ProductId>
{
public static ProductId Parse(string s, IFormatProvider? provider)
=> new(Guid.Parse(s));
public static bool TryParse(string? s, IFormatProvider? provider, out ProductId result)
{
if (Guid.TryParse(s, out var guid))
{
result = new ProductId(guid);
return true;
}
result = default;
return false;
}
public override string ToString() => Value.ToString();
}
Usage
With the attribute applied, the type automatically uses the converter - no additional configuration needed:
var productId = new ProductId(Guid.NewGuid());
// Just works - no special JsonSerializerOptions needed!
string json = JsonSerializer.Serialize(productId);
ProductId deserialized = JsonSerializer.Deserialize<ProductId>(json);
Advanced Usage
More Examples
String-based value type:
[JsonConverter(typeof(JsonParsableConverter<CustomerName>))]
public readonly record struct CustomerName(string Value) : IParsable<CustomerName>
{
public static CustomerName Parse(string s, IFormatProvider? provider)
=> new(s);
public static bool TryParse(string? s, IFormatProvider? provider, out CustomerName result)
{
result = new CustomerName(s ?? string.Empty);
return s != null;
}
public override string ToString() => Value;
}
Complex value type with validation:
[JsonConverter(typeof(JsonParsableConverter<Email>))]
public readonly record struct Email : IParsable<Email>
{
private readonly string _value;
public Email(string value)
{
if (!IsValid(value))
throw new ArgumentException("Invalid email format", nameof(value));
_value = value;
}
public static Email Parse(string s, IFormatProvider? provider)
{
if (!IsValid(s))
throw new FormatException($"Invalid email format: {s}");
return new Email(s);
}
public static bool TryParse(string? s, IFormatProvider? provider, out Email result)
{
if (s != null && IsValid(s))
{
result = new Email(s);
return true;
}
result = default;
return false;
}
private static bool IsValid(string email)
=> !string.IsNullOrWhiteSpace(email) && email.Contains('@');
public override string ToString() => _value;
}
Using in Complex Types
Since the converter is applied via attributes, it works seamlessly in complex objects:
public class Order
{
public OrderId Id { get; set; }
public CustomerId CustomerId { get; set; }
public Money TotalAmount { get; set; }
public DateOnly OrderDate { get; set; }
}
public class Customer
{
public CustomerId Id { get; set; }
public CustomerName Name { get; set; }
public Email Email { get; set; }
}
// No special configuration needed - just serialize!
var customer = new Customer
{
Id = CustomerId.Parse("12345", null),
Name = new CustomerName("John Doe"),
Email = Email.Parse("john@example.com", null)
};
string json = JsonSerializer.Serialize(customer);
Customer deserialized = JsonSerializer.Deserialize<Customer>(json);
Why IParsable?
The IParsable<T>
interface was introduced in .NET 7 as a standard way to define parsing behavior for custom types. Using this pattern with JSON serialization provides:
- Consistency: Same parsing logic for JSON, string manipulation, and user input
- Maintainability: Single source of truth for parsing logic
- Framework Support: Leverages built-in .NET abstractions
- Type Safety: Compile-time guarantees with generic constraints
Performance
This converter is designed for high performance:
- Zero allocations for value type conversions
- Minimal overhead compared to manual serialization
- Efficient string handling using
Utf8JsonReader/Writer
Requirements
- .NET 9.0 or higher
- System.Text.Json
Contributing
Contributions are welcome! Please feel free to submit a Pull Request.
License
This project is licensed under the MIT License - see the LICENSE file for details.
Acknowledgments
This converter is inspired by the need for better value object support in System.Text.Json and is based on patterns from the MicroPlumberd project.
Product | Versions Compatible and additional computed target framework versions. |
---|---|
.NET | net9.0 is compatible. net9.0-android was computed. net9.0-browser was computed. net9.0-ios was computed. net9.0-maccatalyst was computed. net9.0-macos was computed. net9.0-tvos was computed. net9.0-windows was computed. net10.0 was computed. net10.0-android was computed. net10.0-browser was computed. net10.0-ios was computed. net10.0-maccatalyst was computed. net10.0-macos was computed. net10.0-tvos was computed. net10.0-windows was computed. |
-
net9.0
- No dependencies.
NuGet packages (2)
Showing the top 2 NuGet packages that depend on ModelingEvolution.JsonParsableConverter:
Package | Downloads |
---|---|
ModelingEvolution.NetworkManager
A .NET wrapper for NetworkManager D-Bus interface providing comprehensive network management capabilities for Linux systems. Supports WiFi, Ethernet, bridging, and advanced network configuration. |
|
ModelingEvolution.Ipv4
A lightweight and high-performance IPv4 address library for .NET. Provides strongly-typed IPv4 addresses, network calculations, CIDR notation support, and JSON serialization. Perfect for network programming, configuration management, and Domain-Driven Design applications. |
GitHub repositories
This package is not used by any popular GitHub repositories.
Version | Downloads | Last Updated |
---|---|---|
1.0.0 | 321 | 7/6/2025 |