[CSHARP-1351] ObjectSerializer should not be dependent on the order of the _t and _v elements Created: 17/Jul/15  Updated: 02/Apr/16  Resolved: 23/Jul/15

Status: Closed
Project: C# Driver
Component/s: Serialization
Affects Version/s: 1.10
Fix Version/s: 1.10.1, 2.0.2, 2.1

Type: Bug Priority: Major - P3
Reporter: Jared Wadsworth Assignee: Robert Stam
Resolution: Done Votes: 0
Labels: cs
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified
Environment:

C# Driver 1.10.0.62, mongo 2.6.10 on Ubuntu


Issue Links:
Related

 Description   

Customer reported this issue. They receive an exception when the driver attempts to deserialize documents:

Failed EXCEPTION: System.IO.FileFormatException: An error occurred while deserializing the Fields property of class Expected element name to be '_t', not '_v'. ---> System.IO.FileFormatException: Expected element name to be '_t', not '_v'.
at MongoDB.Bson.IO.BsonReader.VerifyName(String expectedName)
at MongoDB.Bson.Serialization.Serializers.EnumerableSerializerBase`1.Deserialize(BsonReader bsonReader, Type nominalType, Type actualType, IBsonSerializationOptions options)
at MongoDB.Bson.Serialization.BsonClassMapSerializer.DeserializeMemberValue(BsonReader bsonReader, BsonMemberMap memberMap)
— End of inner exception stack trace —
at MongoDB.Bson.Serialization.BsonClassMapSerializer.DeserializeMemberValue(BsonReader bsonReader, BsonMemberMap memberMap)
at MongoDB.Bson.Serialization.BsonClassMapSerializer.Deserialize(BsonReader bsonReader, Type nominalType, Type actualType, IBsonSerializationOptions options)
at MongoDB.Bson.Serialization.Serializers.EnumerableSerializerBase`1.Deserialize(BsonReader bsonReader, Type nominalType, Type actualType, IBsonSerializationOptions options)
at MongoDB.Bson.Serialization.BsonClassMapSerializer.DeserializeMemberValue(BsonReader bsonReader, BsonMemberMap memberMap)

Customer provided code sample:

Here's the call stack:

 at MongoDB.Bson.IO.BsonReader.VerifyName(String expectedName)
   at MongoDB.Bson.Serialization.Serializers.EnumerableSerializerBase`1.Deserialize(BsonReader bsonReader, Type nominalType, Type actualType, IBsonSerializationOptions options)
   at MongoDB.Bson.Serialization.BsonClassMapSerializer.DeserializeMemberValue(BsonReader bsonReader, BsonMemberMap memberMap)
   --- End of inner exception stack trace ---
   at MongoDB.Bson.Serialization.BsonClassMapSerializer.DeserializeMemberValue(BsonReader bsonReader, BsonMemberMap memberMap)
   at MongoDB.Bson.Serialization.BsonClassMapSerializer.Deserialize(BsonReader bsonReader, Type nominalType, Type actualType, IBsonSerializationOptions options)
   at MongoDB.Bson.Serialization.Serializers.EnumerableSerializerBase`1.Deserialize(BsonReader bsonReader, Type nominalType, Type actualType, IBsonSerializationOptions options)
   at MongoDB.Bson.Serialization.BsonClassMapSerializer.DeserializeMemberValue(BsonReader bsonReader, BsonMemberMap memberMap)
   --- End of inner exception stack trace ---
   at MongoDB.Bson.Serialization.BsonClassMapSerializer.DeserializeMemberValue(BsonReader bsonReader, BsonMemberMap memberMap)
   at MongoDB.Bson.Serialization.BsonClassMapSerializer.Deserialize(BsonReader bsonReader, Type nominalType, Type actualType, IBsonSerializationOptions options)
   at MongoDB.Bson.Serialization.BsonClassMapSerializer.Deserialize(BsonReader bsonReader, Type nominalType, IBsonSerializationOptions options)
   at MongoDB.Driver.Internal.MongoReplyMessage`1.ReadBodyFrom(BsonBuffer buffer)
   at MongoDB.Driver.Internal.MongoConnection.ReceiveMessage[TDocument](BsonBinaryReaderSettings readerSettings, IBsonSerializer serializer, IBsonSerializationOptions serializationOptions)
   at MongoDB.Driver.Operations.QueryOperation`1.GetFirstBatch(IConnectionProvider connectionProvider)
   at MongoDB.Driver.Operations.QueryOperation`1.Execute(IConnectionProvider connectionProvider)
   at System.Linq.Enumerable.WhereSelectEnumerableIterator`2.MoveNext()
   at System.Linq.Enumerable.ToDictionary[TSource,TKey,TElement](IEnumerable`1 source, Func`2 keySelector, Func`2 elementSelector, IEqualityComparer`1 comparer)
   at System.Linq.Enumerable.ToDictionary[TSource,TKey](IEnumerable`1 source, Func`2 keySelector)
   at OT.GC.DataMart.ETL.ReservationHistory.Repository.MongoDb.MongoDbReservationHistoryRepository.Get(Int64 rid, String reservationId)

and also this reduced sample which reproduces the error:

namespace WikiExampleConsole
{
  public class TestClass
  {
    public object SomeData;
  }
 
  class Program
  {
    static void Main(string[] args)
    {
      string rawJsonTFirst = "{ \"SomeData\" : { \"_t\" : \"System.Object[]\", \"_v\" : [] } }";
      Console.WriteLine("_t first {0}", BsonSerializer.Deserialize<TestClass>(rawJsonTFirst)); // succeeds
 
      string rawJsonVFirst = "{ \"SomeData\" : { \"_v\" : [], \"_t\" : \"System.Object[]\" } }";
      Console.WriteLine("_v first {0}", BsonSerializer.Deserialize<TestClass>(rawJsonVFirst)); // throws
    }
  }
}



 Comments   
Comment by Githook User [ 23/Jul/15 ]

Author:

{u'username': u'rstam', u'name': u'rstam', u'email': u'robert@robertstam.org'}

Message: CSHARP-1351: Change ObjectSerializer to not be dependent on the order of the discriminator and value elements.
Branch: v2.0.x
https://github.com/mongodb/mongo-csharp-driver/commit/a988b76e6dabec13474df34fab9dab432043689f

Comment by Githook User [ 23/Jul/15 ]

Author:

{u'username': u'rstam', u'name': u'rstam', u'email': u'robert@robertstam.org'}

Message: CSHARP-1351: Deserializing discriminated objects should not be dependent on the order of the _t and _v elements.
Branch: v1.x
https://github.com/mongodb/mongo-csharp-driver/commit/de62d019dae7831deade4c5cca418a230a8b4c1f

Comment by Githook User [ 23/Jul/15 ]

Author:

{u'username': u'rstam', u'name': u'rstam', u'email': u'robert@robertstam.org'}

Message: CSHARP-1351: Change ObjectSerializer to not be dependent on the order of the discriminator and value elements.
Branch: master
https://github.com/mongodb/mongo-csharp-driver/commit/f27d20e14d56dbfd70404f372635a952e66e8edf

Comment by Robert Stam [ 18/Jul/15 ]

This has never been a problem before because the C# driver itself is internally consistent in the order that it uses for the _t and _v elements.

But if something external to the driver results in the elements being reordered the driver should not be affected by that. So we've changed the Deserialize method to not depend on the order of the fields.

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