ktsu.RoundTripStringJsonConverter 1.0.5-pre.4
ktsu.RoundTripStringJsonConverter
A versatile JSON converter factory that serializes objects using their ToString method and deserializes using FromString, Parse, Create, or Convert methods.
Introduction
RoundTripStringJsonConverter is a powerful JSON converter factory for System.Text.Json that simplifies serialization and deserialization of custom types by leveraging their string representation methods. It automatically detects and uses the most appropriate conversion method from a prioritized list: FromString, Parse, Create, or Convert. This approach is particularly useful for value types, strong types, domain objects, and any other types where a string representation makes logical sense.
Features
- Multiple Conversion Methods: Supports
FromString,Parse,Create, andConvertmethods with intelligent priority selection - Automatic Type Detection: Automatically identifies types with compatible conversion methods
- Method Priority System: Uses
FromStringfirst, thenParse,Create, and finallyConvert - String-Based Serialization: Converts objects to and from JSON using their string representation
- Property Name Support: Works with both JSON values and property names (dictionary keys)
- Reflection Optimization: Uses cached reflection for improved performance
- Generic Method Support: Handles both generic and non-generic conversion methods
- Comprehensive Error Handling: Graceful handling of invalid types and conversion failures
Installation
Package Manager Console
Install-Package ktsu.RoundTripStringJsonConverter
.NET CLI
dotnet add package ktsu.RoundTripStringJsonConverter
Package Reference
<PackageReference Include="ktsu.RoundTripStringJsonConverter" Version="x.y.z" />
Usage Examples
Basic Example with FromString
using System.Text.Json;
using ktsu.RoundTripStringJsonConverter;
// Configure the converter in your JsonSerializerOptions
var options = new JsonSerializerOptions();
options.Converters.Add(new RoundTripStringJsonConverterFactory());
// Example custom type with ToString and FromString
public class UserId
{
public string Value { get; set; }
public static UserId FromString(string value) => new() { Value = value };
public override string ToString() => Value;
}
// Serialization
var userId = new UserId { Value = "USER-12345" };
string json = JsonSerializer.Serialize(userId, options);
// json is now: "USER-12345"
// Deserialization
UserId deserialized = JsonSerializer.Deserialize<UserId>(json, options);
// deserialized.Value is now: "USER-12345"
Using Different Conversion Methods
The converter automatically detects and uses the appropriate method based on priority:
// Type with Parse method (common in .NET)
public class ProductCode
{
public string Code { get; set; }
public static ProductCode Parse(string code) => new() { Code = code };
public override string ToString() => Code;
}
// Type with Create method (factory pattern)
public class OrderId
{
public string Id { get; set; }
public static OrderId Create(string id) => new() { Id = id };
public override string ToString() => Id;
}
// Type with Convert method
public class CategoryName
{
public string Name { get; set; }
public static CategoryName Convert(string name) => new() { Name = name };
public override string ToString() => Name;
}
// All types work seamlessly with the same converter
var options = new JsonSerializerOptions();
options.Converters.Add(new RoundTripStringJsonConverterFactory());
var product = ProductCode.Parse("PROD-ABC");
var order = OrderId.Create("ORD-001");
var category = CategoryName.Convert("Electronics");
// All serialize and deserialize correctly
string productJson = JsonSerializer.Serialize(product, options);
string orderJson = JsonSerializer.Serialize(order, options);
string categoryJson = JsonSerializer.Serialize(category, options);
Method Priority Example
When multiple methods are available, the converter uses this priority order:
public class MultiMethodType
{
public string Value { get; set; }
// Highest priority - will be used
public static MultiMethodType FromString(string value) => new() { Value = $"FromString:{value}" };
// Lower priority - will be ignored
public static MultiMethodType Parse(string value) => new() { Value = $"Parse:{value}" };
public override string ToString() => Value;
}
// FromString method will be used for deserialization
var result = JsonSerializer.Deserialize<MultiMethodType>("\"test\"", options);
// result.Value will be "FromString:test"
Integration with Other Converters
using System.Text.Json;
using System.Text.Json.Serialization;
using ktsu.RoundTripStringJsonConverter;
var options = new JsonSerializerOptions
{
WriteIndented = true,
PropertyNamingPolicy = JsonNamingPolicy.CamelCase,
Converters =
{
new RoundTripStringJsonConverterFactory(),
new JsonStringEnumConverter()
}
};
// Now both enum values and custom types with conversion methods will be handled appropriately
Advanced Usage
Working with Collections of Custom Types
using System.Text.Json;
using ktsu.RoundTripStringJsonConverter;
// Setup serializer options with the converter
var options = new JsonSerializerOptions();
options.Converters.Add(new RoundTripStringJsonConverterFactory());
// A collection of custom types
List<UserId> userIds = new()
{
UserId.FromString("USER-001"),
UserId.FromString("USER-002"),
UserId.FromString("USER-003")
};
// Serialize the collection
string json = JsonSerializer.Serialize(userIds, options);
// json is now: ["USER-001","USER-002","USER-003"]
// Deserialize back to a collection
List<UserId> deserializedIds = JsonSerializer.Deserialize<List<UserId>>(json, options);
Using with Dictionaries as Keys
// Custom types can be used as dictionary keys
var userProducts = new Dictionary<UserId, List<ProductCode>>
{
{ UserId.FromString("USER-001"), [ProductCode.Parse("PROD-A"), ProductCode.Parse("PROD-B")] },
{ UserId.FromString("USER-002"), [ProductCode.Parse("PROD-C")] }
};
string json = JsonSerializer.Serialize(userProducts, options);
// Serializes as a dictionary with string keys
var deserialized = JsonSerializer.Deserialize<Dictionary<UserId, List<ProductCode>>>(json, options);
// Keys are properly deserialized back to UserId objects
Complex Domain Objects
public class Order
{
public OrderId Id { get; set; }
public UserId CustomerId { get; set; }
public List<ProductCode> Products { get; set; }
public Dictionary<CategoryName, int> CategoryCounts { get; set; }
public DateTime OrderDate { get; set; }
}
// All custom types are automatically handled
var order = new Order
{
Id = OrderId.Create("ORD-001"),
CustomerId = UserId.FromString("USER-123"),
Products = [ProductCode.Parse("PROD-A"), ProductCode.Parse("PROD-B")],
CategoryCounts = new Dictionary<CategoryName, int>
{
{ CategoryName.Convert("Electronics"), 2 }
},
OrderDate = DateTime.UtcNow
};
string json = JsonSerializer.Serialize(order, options);
Order deserializedOrder = JsonSerializer.Deserialize<Order>(json, options);
API Reference
RoundTripStringJsonConverterFactory
The primary class for integrating with System.Text.Json serialization.
Methods
| Name | Return Type | Description |
|---|---|---|
CanConvert(Type typeToConvert) |
bool |
Determines if a type can be converted by checking for compatible conversion methods |
CreateConverter(Type typeToConvert, JsonSerializerOptions options) |
JsonConverter |
Creates a type-specific converter instance |
Supported Conversion Methods
The converter looks for static methods in this priority order:
- FromString(string) - Highest priority, commonly used for custom types
- Parse(string) - Second priority, follows .NET conventions (like int.Parse)
- Create(string) - Third priority, factory pattern methods
- Convert(string) - Lowest priority, general conversion methods
Compatibility Requirements
For a type to work with RoundTripStringJsonConverter, it must meet these requirements:
- Have a public static method with one of the supported names (
FromString,Parse,Create, orConvert) - The method must take a single
stringparameter - The method must return an instance of the declaring type
- Override
ToString()to provide a string representation that can be reversed by the conversion method
Valid Method Signatures
// All of these are valid conversion methods:
public static MyType FromString(string value) { ... }
public static MyType Parse(string value) { ... }
public static MyType Create(string value) { ... }
public static MyType Convert(string value) { ... }
Invalid Method Signatures
// These will NOT work:
public MyType FromString(string value) { ... } // Not static
public static MyType FromString(int value) { ... } // Wrong parameter type
public static string FromString(string value) { ... } // Wrong return type
public static MyType FromString(string value, IFormatProvider provider) { ... } // Too many parameters
Performance Considerations
- Reflection Caching: Method information is cached for improved performance on repeated conversions
- Large Collections: Tested with collections of 1000+ items
- Memory Efficiency: Minimal memory overhead per conversion
- Thread Safety: The converter factory is thread-safe
Error Handling
The converter provides comprehensive error handling:
- Invalid JSON Types: Throws
JsonExceptionfor non-string JSON tokens - Conversion Failures: Propagates exceptions from conversion methods
- Missing Methods: Types without valid conversion methods are ignored
- Null Arguments: Proper
ArgumentNullExceptionhandling
Migration from ToStringJsonConverter
If you're migrating from the previous ToStringJsonConverter:
- Update package reference to
ktsu.RoundTripStringJsonConverter - Update using statements:
using ktsu.RoundTripStringJsonConverter; - Update converter instantiation:
new RoundTripStringJsonConverterFactory() - Your existing
FromStringmethods will continue to work unchanged - You can now also use
Parse,Create, orConvertmethods
Contributing
Contributions are welcome! Here's how you can help:
- Fork the repository
- Create your feature branch (
git checkout -b feature/amazing-feature) - Commit your changes (
git commit -m 'Add some amazing feature') - Push to the branch (
git push origin feature/amazing-feature) - Open a Pull Request
Please make sure to update tests as appropriate.
License
This project is licensed under the MIT License - see the LICENSE.md file for details.
Showing the top 20 packages that depend on ktsu.RoundTripStringJsonConverter.
| Packages | Downloads |
|---|---|
|
ktsu.AppDataStorage
Application data management library using JSON serialization to save and load data in the user's app data folder.
|
21 |
|
ktsu.AppDataStorage
Application data management library using JSON serialization to save and load data in the user's app data folder.
|
20 |
|
ktsu.AppDataStorage
Application data management library using JSON serialization to save and load data in the user's app data folder.
|
19 |
|
ktsu.AppDataStorage
Application data management library using JSON serialization to save and load data in the user's app data folder.
|
18 |
|
ktsu.AppDataStorage
Application data management library using JSON serialization to save and load data in the user's app data folder.
|
16 |
|
ktsu.AppDataStorage
Application data management library using JSON serialization to save and load data in the user's app data folder.
|
15 |
.NET 5.0
- No dependencies.
.NET Standard 2.1
- System.Text.Json (>= 8.0.5)
- System.Memory (>= 4.6.3)
.NET Standard 2.0
- System.Threading.Tasks.Extensions (>= 4.6.3)
- System.Text.Json (>= 8.0.5)
- System.Memory (>= 4.6.3)
.NET 8.0
- No dependencies.
.NET 7.0
- No dependencies.
.NET 6.0
- No dependencies.
.NET 9.0
- No dependencies.
| Version | Downloads | Last updated |
|---|---|---|
| 1.0.5-pre.4 | 18 | 11/24/2025 |
| 1.0.5-pre.3 | 17 | 11/23/2025 |
| 1.0.5-pre.2 | 15 | 11/23/2025 |
| 1.0.5-pre.1 | 15 | 11/23/2025 |
| 1.0.4 | 20 | 09/11/2025 |
| 1.0.3 | 15 | 08/25/2025 |