Serializers
Cratis Applications provides a comprehensive set of custom serializers for MongoDB to handle common .NET types that don’t have built-in MongoDB support or need special handling.
Built-in Serializers
Section titled “Built-in Serializers”The following serializers are automatically registered when you call UseCratisMongoDB():
DateTimeOffset Support
Section titled “DateTimeOffset Support”Class: DateTimeOffsetSupportingBsonDateTimeSerializer
Provides proper serialization of DateTimeOffset values, preserving timezone information that would otherwise be lost with MongoDB’s default DateTime handling.
public class MyDocument{ public DateTimeOffset CreatedAt { get; set; } = DateTimeOffset.Now; public DateTimeOffset UpdatedAt { get; set; }}The serializer supports different BSON representations:
BsonType.DateTime(default)BsonType.StringBsonType.Int64
DateOnly Serializer
Section titled “DateOnly Serializer”Class: DateOnlySerializer
Handles .NET 6+ DateOnly types, storing them efficiently in MongoDB:
public class EventRecord{ public DateOnly EventDate { get; set; } public string Description { get; set; }}TimeOnly Serializer
Section titled “TimeOnly Serializer”Class: TimeOnlySerializer
Handles .NET 6+ TimeOnly types for time-of-day values:
public class Schedule{ public TimeOnly StartTime { get; set; } public TimeOnly EndTime { get; set; }}Type Serializer
Section titled “Type Serializer”Class: TypeSerializer
Serializes System.Type instances, useful for polymorphic scenarios or when storing type information:
public class TypedDocument{ public Type DocumentType { get; set; } public object Data { get; set; }}Guid Configuration
Section titled “Guid Configuration”One of the most important default configurations is for System.Guid. MongoDB historically used a legacy GUID representation that could cause issues. Cratis Applications configures Guids to use the standard representation:
// This is done automatically during setupBsonDefaults.GuidRepresentation = GuidRepresentation.Standard;BsonDefaults.GuidRepresentationMode = GuidRepresentationMode.V3;This ensures that:
- Guids are stored in a predictable format
- They work correctly with .NET applications
- There are no surprises when viewing data in MongoDB tools
Custom Serializers
Section titled “Custom Serializers”You can register additional serializers if needed:
Using MongoDB’s Registration
Section titled “Using MongoDB’s Registration”BsonSerializer.RegisterSerializer(new MyCustomSerializer());Using Serialization Providers
Section titled “Using Serialization Providers”For more complex scenarios, implement IBsonSerializationProvider:
public class MySerializationProvider : IBsonSerializationProvider{ public IBsonSerializer GetSerializer(Type type) { if (type == typeof(MyCustomType)) { return new MyCustomTypeSerializer(); }
return null; }}
// Register the providerBsonSerializer.RegisterSerializationProvider(new MySerializationProvider());Serializer Configuration
Section titled “Serializer Configuration”Some serializers support configuration through interfaces:
Representation Configurable
Section titled “Representation Configurable”Serializers implementing IRepresentationConfigurable<T> can be configured for different BSON representations:
// Configure DateTimeOffset to serialize as stringvar serializer = new DateTimeOffsetSupportingBsonDateTimeSerializer() .WithRepresentation(BsonType.String);
BsonSerializer.RegisterSerializer(serializer);Polymorphic Serialization
Section titled “Polymorphic Serialization”For complex inheritance hierarchies, the framework includes custom discriminator handling:
Custom Object Discriminator Convention
Section titled “Custom Object Discriminator Convention”The CustomObjectDiscriminatorConvention provides better handling of polymorphic types by using more readable type strings instead of .NET’s default assembly-qualified names.
public abstract class BaseDocument{ public string Id { get; set; }}
public class TextDocument : BaseDocument{ public string Content { get; set; }}
public class ImageDocument : BaseDocument{ public byte[] ImageData { get; set; }}The discriminator will use simplified type names making the stored documents more readable and portable.
Performance Considerations
Section titled “Performance Considerations”Serializer Caching
Section titled “Serializer Caching”MongoDB serializers are cached by type, so there’s no performance penalty for using custom serializers once they’re registered.
Concept Serializers
Section titled “Concept Serializers”The Concept serializers are optimized to serialize only the underlying value, not the wrapper object, providing efficient storage and retrieval.
Error Handling
Section titled “Error Handling”Serializers include comprehensive error handling:
- Type validation: Ensures only appropriate types are serialized
- Null handling: Proper null value handling across all serializers
- Format validation: Validates input data before serialization
Next Steps
Section titled “Next Steps”- Learn about Concept serialization for domain-driven design
- Explore Class Mapping for custom type mapping
- Configure Naming Policies for consistent field naming