Skip to content

Serialization

Taiizor edited this page Dec 18, 2024 · 1 revision

🔄 Serialization

Available Packages

UUID library provides serialization support through two separate packages:

System.Text.Json Package

Install via NuGet:

dotnet add package UUID.Serialization.System

Newtonsoft.Json Package

Install via NuGet:

dotnet add package UUID.Serialization.Newtonsoft

Basic Usage Examples

1. System.Text.Json Basic Usage

// Configure JsonSerializerOptions
var options = new JsonSerializerOptions();
options.Converters.Add(new UUIDConverter());

// Create a UUID
var uuid = UUID.New();

// Serialize
string json = JsonSerializer.Serialize(uuid, options);

// Deserialize
UUID deserialized = JsonSerializer.Deserialize<UUID>(json, options);

2. Newtonsoft.Json Basic Usage

// Configure JsonSerializerSettings
var settings = new JsonSerializerSettings();
settings.Converters.Add(new UUIDConverter());

// Create a UUID
var uuid = UUID.New();

// Serialize
string json = JsonConvert.SerializeObject(uuid, settings);

// Deserialize
UUID deserialized = JsonConvert.DeserializeObject<UUID>(json, settings);

Advanced Examples

1. Model with UUID Collection

public class Team
{
    public string Name { get; set; }
    public List<UUID> MemberIds { get; set; }
}

var team = new Team 
{ 
    Name = "Development Team",
    MemberIds = new List<UUID> { UUID.New(), UUID.New() }
};

// System.Text.Json
string json = JsonSerializer.Serialize(team, options);
Team deserializedTeam = JsonSerializer.Deserialize<Team>(json, options);

// Newtonsoft.Json
string json = JsonConvert.SerializeObject(team, settings);
Team deserializedTeam = JsonConvert.DeserializeObject<Team>(json, settings);

2. Dictionary with UUID Keys

// Create a dictionary with UUID keys
Dictionary<UUID, string> userNames = new()
{
    { UUID.New(), "John Doe" },
    { UUID.New(), "Jane Smith" }
};

// System.Text.Json
string json = JsonSerializer.Serialize(userNames, options);
var deserializedDict = JsonSerializer.Deserialize<Dictionary<UUID, string>>(json, options);

// Newtonsoft.Json
string json = JsonConvert.SerializeObject(userNames, settings);
var deserializedDict = JsonConvert.DeserializeObject<Dictionary<UUID, string>>(json, settings);

3. Custom Property Names

public class UserProfile
{
    [JsonPropertyName("user_id")]        // System.Text.Json
    [JsonProperty("user_id")]            // Newtonsoft.Json
    public UUID Id { get; set; }

    [JsonPropertyName("display_name")]    // System.Text.Json
    [JsonProperty("display_name")]        // Newtonsoft.Json
    public string Name { get; set; }
}

// The serialized JSON will use custom property names:
// {
//   "user_id": "...",
//   "display_name": "John Doe"
// }

4. Nullable UUID Properties

public class Document
{
    public UUID Id { get; set; }
    public UUID? ParentId { get; set; }    // Nullable UUID
    public string Title { get; set; }
}

var document = new Document 
{ 
    Id = UUID.New(),
    ParentId = null,        // Will be serialized as null
    Title = "My Document"
};

Best Practices

1. Global Configuration in ASP.NET Core

// System.Text.Json
public void ConfigureServices(IServiceCollection services)
{
    services.AddControllers()
            .AddJsonOptions(options =>
            {
                options.JsonSerializerOptions.Converters.Add(new UUIDConverter());
            });
}

// Newtonsoft.Json
public void ConfigureServices(IServiceCollection services)
{
    services.AddControllers()
            .AddNewtonsoftJson(options =>
            {
                options.SerializerSettings.Converters.Add(new UUIDConverter());
            });
}

2. Custom Converter Implementation

public class CustomUUIDConverter : JsonConverter<UUID>
{
    public override UUID Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
    {
        string value = reader.GetString();
        return value != null ? UUID.Parse($"prefix_{value}") : default;
    }

    public override void Write(Utf8JsonWriter writer, UUID value, JsonSerializerOptions options)
    {
        writer.WriteStringValue($"prefix_{value}");
    }
}

Error Handling

1. System.Text.Json Error Handling

try
{
    string invalidJson = "\"invalid-uuid-format\"";
    UUID uuid = JsonSerializer.Deserialize<UUID>(invalidJson, options);
}
catch (JsonException ex)
{
    Console.WriteLine($"Failed to deserialize UUID: {ex.Message}");
}

2. Newtonsoft.Json Error Handling

try
{
    string invalidJson = "\"invalid-uuid-format\"";
    UUID uuid = JsonConvert.DeserializeObject<UUID>(invalidJson, settings);
}
catch (JsonReaderException ex)
{
    Console.WriteLine($"Failed to deserialize UUID: {ex.Message}");
}

Performance Considerations

  • Both serialization implementations are optimized for performance
  • Run benchmarks to compare performance:
    dotnet run -c Release --project benchmark/UUID.Serialization.System.Benchmarks
    dotnet run -c Release --project benchmark/UUID.Serialization.Newtonsoft.Benchmarks

Additional Tips

  1. Configure serializer settings/options once and reuse them
  2. Use the appropriate package based on your project's existing JSON library
  3. Always include proper error handling for deserialization
  4. Consider using dependency injection for serializer configurations
  5. Test serialization with various UUID formats and edge cases