Hi,
we are using explicit field level encryption and MongoDbDriver 2.17.1
This is how we decrypt the value that should become BsonDocument:
decodedWorkflow.CustomFields = (await clientEncryption.DecryptAsync(workflow.CustomFields)).AsBsonDocument;
All the casts that I try to do to get BsonDocument, instead I get RawBsonDocument. All is good until it comes to serialize to Newtonsoft.Json to return the data from the controller.
It throws this error:
System.InvalidCastException: Specified cast is not valid.
at MongoDB.Bson.BsonValue.System.IConvertible.ToType(Type conversionType, IFormatProvider provider)
at Newtonsoft.Json.JsonWriter.ResolveConvertibleValue(IConvertible convertible, PrimitiveTypeCode& typeCode, Object& value)
at Newtonsoft.Json.JsonWriter.WriteValue(JsonWriter writer, PrimitiveTypeCode typeCode, Object value)
at Newtonsoft.Json.Serialization.JsonSerializerInternalWriter.SerializeObject(JsonWriter writer, Object value, JsonObjectContract contract, JsonProperty member, JsonContainerContract collectionContract, JsonProperty containerProperty)
at Newtonsoft.Json.Serialization.JsonSerializerInternalWriter.SerializeList(JsonWriter writer, IEnumerable values, JsonArrayContract contract, JsonProperty member, JsonContainerContract collectionContract, JsonProperty containerProperty)
at Newtonsoft.Json.Serialization.JsonSerializerInternalWriter.SerializeObject(JsonWriter writer, Object value, JsonObjectContract contract, JsonProperty member, JsonContainerContract collectionContract, JsonProperty containerProperty)
at Newtonsoft.Json.Serialization.JsonSerializerInternalWriter.SerializeList(JsonWriter writer, IEnumerable values, JsonArrayContract contract, JsonProperty member, JsonContainerContract collectionContract, JsonProperty containerProperty)
at Newtonsoft.Json.Serialization.JsonSerializerInternalWriter.SerializeObject(JsonWriter writer, Object value, JsonObjectContract contract, JsonProperty member, JsonContainerContract collectionContract, JsonProperty containerProperty)
at Newtonsoft.Json.Serialization.JsonSerializerInternalWriter.Serialize(JsonWriter jsonWriter, Object value, Type objectType)
at Newtonsoft.Json.JsonSerializer.SerializeInternal(JsonWriter jsonWriter, Object value, Type objectType)
at Microsoft.AspNetCore.Mvc.Formatters.NewtonsoftJsonOutputFormatter.WriteResponseBodyAsync(OutputFormatterWriteContext context, Encoding selectedEncoding)
at Microsoft.AspNetCore.Mvc.Formatters.NewtonsoftJsonOutputFormatter.WriteResponseBodyAsync(OutputFormatterWriteContext context, Encoding selectedEncoding)
at Microsoft.AspNetCore.Mvc.Formatters.NewtonsoftJsonOutputFormatter.WriteResponseBodyAsync(OutputFormatterWriteContext context, Encoding selectedEncoding)
at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeNextResultFilterAsync>g__Awaited|30_0[TFilter,TFilterAsync](ResourceInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)
at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.Rethrow(ResultExecutedContextSealed context)
at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.ResultNext[TFilter,TFilterAsync](State& next, Scope& scope, Object& state, Boolean& isCompleted)
at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.InvokeResultFilters()
It is the method IConvertible.ToType of MongoDB.BSON package version 2.17.0 that throws the error for BsonNull field:
object IConvertible.ToType(Type conversionType, IFormatProvider provider)
{
if (conversionType == typeof(object))
{
return this;
}
switch (BsonType)
{
case BsonType.Boolean: return Convert.ChangeType(this.AsBoolean, conversionType, provider);
case BsonType.DateTime: return Convert.ChangeType(this.ToUniversalTime(), conversionType, provider);
case BsonType.Decimal128: return Convert.ChangeType(this.AsDecimal128, conversionType, provider);
case BsonType.Double: return Convert.ChangeType(this.AsDouble, conversionType, provider);
case BsonType.Int32: return Convert.ChangeType(this.AsInt32, conversionType, provider);
case BsonType.Int64: return Convert.ChangeType(this.AsInt64, conversionType, provider);
case BsonType.ObjectId: return Convert.ChangeType(this.AsObjectId, conversionType, provider);
case BsonType.String: return Convert.ChangeType(this.AsString, conversionType, provider);
default: throw new InvalidCastException();
}
}
Does this method needs to support Bson.Null type because this is regular Bson type?
I have solved this by converting tostring and then parsing to BsonDocument, but I dont think it is the best solution.
Did someone have the similar problem?
BsonDocument.Parse((await clientEncryption.DecryptAsync(workflow.CustomFields)).ToString());```
I also tried:
BsonDocument.Parse(JsonConvert.SerializeObject(BsonTypeMapper.MapToDotNetValue(await clientEncryption.DecryptAsync(workflow.CustomFields))));
And on that way it returns BsonDocument, but shouldnt it be sufficient just to use AsBsonDocument?