diff --git a/src/providers/WorkflowCore.Persistence.MongoDB/README.md b/src/providers/WorkflowCore.Persistence.MongoDB/README.md index 9668e393..4fd8413d 100644 --- a/src/providers/WorkflowCore.Persistence.MongoDB/README.md +++ b/src/providers/WorkflowCore.Persistence.MongoDB/README.md @@ -18,6 +18,43 @@ Use the .UseMongoDB extension method when building your service provider. services.AddWorkflow(x => x.UseMongoDB(@"mongodb://localhost:27017", "workflow")); ``` +### Configuring the ObjectSerializer + +When using MongoDB persistence with user-defined data classes, you need to configure which types are allowed to be deserialized. This is done via the `serializerTypeFilter` parameter: + +```C# +services.AddWorkflow(x => x.UseMongoDB( + @"mongodb://localhost:27017", + "workflow", + serializerTypeFilter: type => + MongoDB.Bson.Serialization.Serializers.ObjectSerializer.DefaultAllowedTypes(type) || + type.FullName?.StartsWith("MyApp.") == true)); +``` + +This configuration allows: +- All default MongoDB allowed types (primitives, collections, etc.) +- Types in your application namespace (e.g., `MyApp.*`) + +**Important:** You must configure the serializer to allow your workflow data types, otherwise you will encounter a `BsonSerializationException` when MongoDB tries to deserialize your data. + +Example for multiple namespaces: + +```C# +services.AddWorkflow(x => x.UseMongoDB( + @"mongodb://localhost:27017", + "workflow", + serializerTypeFilter: type => + { + if (MongoDB.Bson.Serialization.Serializers.ObjectSerializer.DefaultAllowedTypes(type)) + return true; + + var fullName = type.FullName ?? ""; + return fullName.StartsWith("MyApp.") || + fullName.StartsWith("MyCompany.Models.") || + fullName.StartsWith("WorkflowCore."); + })); +``` + ### State object serialization By default (to maintain backwards compatibility), the state object is serialized using a two step serialization process using object -> JSON -> BSON serialization. diff --git a/src/providers/WorkflowCore.Persistence.MongoDB/ServiceCollectionExtensions.cs b/src/providers/WorkflowCore.Persistence.MongoDB/ServiceCollectionExtensions.cs index 9534fe0b..f03205c3 100644 --- a/src/providers/WorkflowCore.Persistence.MongoDB/ServiceCollectionExtensions.cs +++ b/src/providers/WorkflowCore.Persistence.MongoDB/ServiceCollectionExtensions.cs @@ -12,8 +12,11 @@ public static WorkflowOptions UseMongoDB( this WorkflowOptions options, string mongoUrl, string databaseName, - Action configureClient = default) + Action configureClient = default, + Func serializerTypeFilter = null) { + RegisterObjectSerializer(serializerTypeFilter); + options.UsePersistence(sp => { var mongoClientSettings = MongoClientSettings.FromConnectionString(mongoUrl); @@ -35,11 +38,14 @@ public static WorkflowOptions UseMongoDB( public static WorkflowOptions UseMongoDB( this WorkflowOptions options, - Func createDatabase) + Func createDatabase, + Func serializerTypeFilter = null) { if (options == null) throw new ArgumentNullException(nameof(options)); if (createDatabase == null) throw new ArgumentNullException(nameof(createDatabase)); + RegisterObjectSerializer(serializerTypeFilter); + options.UsePersistence(sp => { var db = createDatabase(sp); @@ -53,5 +59,14 @@ public static WorkflowOptions UseMongoDB( return options; } + + private static void RegisterObjectSerializer(Func serializerTypeFilter) + { + if (serializerTypeFilter != null) + { + MongoDB.Bson.Serialization.BsonSerializer.TryRegisterSerializer( + new MongoDB.Bson.Serialization.Serializers.ObjectSerializer(serializerTypeFilter)); + } + } } }