[CSHARP-4593] Find statement with projection throws deserialization error after upgrading to 2.19.x Created: 31/Mar/23  Updated: 28/Apr/23

Status: Backlog
Project: C# Driver
Component/s: None
Affects Version/s: 2.19.0, 2.19.1
Fix Version/s: None

Type: Bug Priority: Minor - P4
Reporter: Ryan Dixon Assignee: Unassigned
Resolution: Unresolved Votes: 1
Labels: find, linq3, project, triage
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified

Quarter: FY23Q2

 Description   

Summary

A relatively simply Find document command began throwing an error after upgrading to v2.19. Works fine in v2.18

Please provide the version of the driver. If applicable, please provide the MongoDB server version and topology (standalone, replica set, or sharded cluster).

driver versions: v2.19 & v2.19.1

Server Version: 4.2,

Running on Azure.CosmosDb, but seems unrelated to the issue

How to Reproduce

            string rtn = await base.Database.Orders.Find<Order>(o =>
                o.RateBasisHistoryId == "ISSHIPZZ-GJJPU-EXSYU-9JHPE.N0P" //Not the order's BsonId but, still unique identifies an order
                )                
            .Project(r => r.Id)
            .FirstOrDefaultAsync();

The above statement throws this error:
System.FormatException: Cannot deserialize a 'String' from BsonType 'Int32'.
   at MongoDB.Bson.Serialization.Serializers.StringSerializer.DeserializeValue(BsonDeserializationContext context, BsonDeserializationArgs args)
   at MongoDB.Bson.Serialization.Serializers.SealedClassSerializerBase`1.Deserialize(BsonDeserializationContext context, BsonDeserializationArgs args)
   at MongoDB.Bson.Serialization.IBsonSerializerExtensions.Deserialize[TValue](IBsonSerializer`1 serializer, BsonDeserializationContext context)
   at MongoDB.Driver.Linq.Linq3Implementation.Serializers.WrappedValueSerializer`1.Deserialize(BsonDeserializationContext context, BsonDeserializationArgs args)
   at MongoDB.Bson.Serialization.IBsonSerializerExtensions.Deserialize[TValue](IBsonSerializer`1 serializer, BsonDeserializationContext context)
   at MongoDB.Driver.Core.Operations.CursorBatchDeserializationHelper.DeserializeBatch[TDocument](RawBsonArray batch, IBsonSerializer`1 documentSerializer, MessageEncoderSettings messageEncoderSettings)
   at MongoDB.Driver.Core.Operations.FindOperation`1.CreateFirstCursorBatch(BsonDocument cursorDocument)
   at MongoDB.Driver.Core.Operations.FindOperation`1.CreateCursor(IChannelSourceHandle channelSource, IChannelHandle channel, BsonDocument commandResult)
   at MongoDB.Driver.Core.Operations.FindOperation`1.ExecuteAsync(RetryableReadContext context, CancellationToken cancellationToken)
   at MongoDB.Driver.Core.Operations.FindOperation`1.ExecuteAsync(IReadBinding binding, CancellationToken cancellationToken)
   at MongoDB.Driver.OperationExecutor.ExecuteReadOperationAsync[TResult](IReadBinding binding, IReadOperation`1 operation, CancellationToken cancellationToken)
   at MongoDB.Driver.MongoCollectionImpl`1.ExecuteReadOperationAsync[TResult](IClientSessionHandle session, IReadOperation`1 operation, ReadPreference readPreference, CancellationToken cancellationToken)
   at MongoDB.Driver.MongoCollectionImpl`1.UsingImplicitSessionAsync[TResult](Func`2 funcAsync, CancellationToken cancellationToken)
   at MongoDB.Driver.IAsyncCursorSourceExtensions.FirstOrDefaultAsync[TDocument](IAsyncCursorSource`1 source, CancellationToken cancellationToken)

Additional Background

Removing the Projection and instead returning the entire Order object avoids the error

Order.Id is definition is:

[BsonId]
public string Id {get; set;}



 Comments   
Comment by Patrick Gilfether [ 28/Apr/23 ]

nick.toth@integrate.com thank you for sharing. I want to be sure we are able to accurately reproduce the bug you are experiencing so that we can investigate it further. Can you please provide a self-contained console application that reproduces the error as well as the server version and execution environment you are using?

Comment by Nick Toth [ 28/Apr/23 ]

I ran into the same issue with the following query after upgrading from 2.18 to 2.19.1

_entitiesCollection.Aggregate()     
    .Match(idsFilter)     
    .Project(         
        e => new { 
            _id = 1, 
            CampaignId = 1,
            Accepted = e.Status.Key == "Accepted" ? 1 : 0,
            Rejected = e.Status.Key == "Rejected" ? 1 : 0,         
        }
    )

I was getting a "Cannot deserialize a 'Guid' from BsonType 'Int32'" error. I was able to work around it by converting from using an anonymous type to a class.

Comment by Ahmed Fwela [ 19/Apr/23 ]

rdixon@etractechnologies.com  do you have by any chance any integer order Ids in your database?

Comment by Ryan Dixon [ 13/Apr/23 ]

I have not had a chance to create a console app for this. Given that I found a workaround, can we downgrade the priority of this? (I can't seem to figure out how to do downgrade this)

Comment by Robert Stam [ 13/Apr/23 ]

Thanks for letting us know that you are also are seeing this issue.

Can you provide a small self-contained console application that reproduces the issue?

Comment by Duma Holand [ 13/Apr/23 ]

I have the same problem with projection after driver update. Temporary workaround is to use LINQ2 provider. Waiting for fix.

Comment by PM Bot [ 10/Apr/23 ]

Hey rdixon@etractechnologies.com, We need additional details to investigate the problem. If this is still an issue for you, please provide the requested information.

Comment by Robert Stam [ 31/Mar/23 ]

Sorry you are running into an issue and thank you for reporting it.

Can you provide a small self-contained console application that reproduces the issue?

Comment by Ryan Dixon [ 31/Mar/23 ]

While I found the workaround below, the original statement is a common pattern in our code and implementing this workaround every (and the associated testing and verification) is non-trivial.

This works:
            MongoDB.Bson.BsonDocument bsonRtn = await base.Database.Orders.Find(o =>
                   o.RateBasisHistoryId == "ISSHIPZZ-GJJPU-EXSYU-9JHPE.N0P" 
                    )
                .Project(Builders<Entities.Order>.Projection.Include(o => o.Id))
                .FirstOrDefaultAsync();
            var rtn = bsonRtn["_id"].ToString();

Generated at Wed Feb 07 21:48:42 UTC 2024 using Jira 9.7.1#970001-sha1:2222b88b221c4928ef0de3161136cc90c8356a66.