I'm using the DocumentDB API of Cosmos DB in Azure. Documents are taken from an EventHub and stored to the database by an Azure function triggered by that EventHub.
The documents I'm saving also contain a couple of enums. Unfortunately these enum values are serialized using their index number instead of enum values (see here: https://i.stack.imgur.com/3nP9o.png). Or, to be more precise, this is what happens when the function is running in Azure. Tests in a local IDE are working fine.
This is the code that is writing to Cosmos/DocumentDB:
DocumentClient = new DocumentClient(new Uri(dbServiceEndpoint), dbAuthKey);
...
var response = DocumentClient.CreateDocumentAsync(UriFactory.CreateDocumentCollectionUri(DatabaseId, CollectionId), tick);
response.Wait();
"tick" is the mentioned object to be stored.
I tried a couple of things to make the document client serialize enums correctly:
Annotation at enum property:
[Newtonsoft.Json.JsonConverter(typeof(StringEnumConverter))] public OrderActionEnum? Action { get; set; }
Annotation at enum defintion:
[Newtonsoft.Json.JsonConverter(typeof(StringEnumConverter))] public enum OrderActionEnum { NEW, CHANGE, DELETE, SNAPSHOT, INITIAL }
Passing converter to constructor of document db client:
DocumentClient = new DocumentClient(new Uri(dbServiceEndpoint), dbAuthKey, new JsonSerializerSettings { Converters = new List<JsonConverter> {new StringEnumConverter()} });
Setting a default serializer:
JsonConvert.DefaultSettings = () => new JsonSerializerSettings { Converters = new List<JsonConverter> {new StringEnumConverter()} };
None of these tries convinced the Cosmos/DocumentDB to store the enum values.
One interesting effect was that the third variant (passing converter to constructor of DocumentClient) resulted in an exception when running Azure (local tests worked fine):
2017-11-24T15:08:55.291 System.MissingMethodException : Method not found: 'Void Microsoft.Azure.Documents.Client.DocumentClient..ctor(System.Uri, System.String, Newtonsoft.Json.JsonSerializerSettings, Microsoft.Azure.Documents.Client.ConnectionPolicy, System.Nullable`1<Microsoft.Azure.Documents.ConsistencyLevel>)'.
at TickAnalysis.DataManager.Persistency.AbstractCosmosClient`1..ctor(ILogger logger,String dbServiceEndpoint,String dbAuthKey,String databaseId,String collectionId)
at TickAnalysis.DataManager.DataManagerFunction.RunStoreOrderEvent(String message,TraceWriter log)
This looked a bit like different versions of the package Microsoft.Azure.DocumentDB are being used. So I compared the DLLs in my local bin with the one deployed for the function in Azure. In both cases it was version 1.19.1.
Now I'm running out of ideas. I could replace the enums by plain string, but I really don't want to do that. Any hints are appreciated.
I'm aware of similar questions being asked before. For example:
- Custom serialisation of C# poco's for DocumentDb
- https://github.com/Azure/azure-webjobs-sdk-script/issues/1679
- Setting a custom json converter for DocumentDb
- Use custom JsonSerializerSettings with DocumentDb in Azure Function
- https://github.com/Azure/azure-webjobs-sdk-script/issues/1679
- https://github.com/Azure/azure-documentdb-dotnet/issues/307
Unfortunately none of these solved my problem.