Uploaded image for project: 'C# Driver'
  1. C# Driver
  2. CSHARP-4261

LinqProvider.V3 breaks custom BsonSerializerAttribute

    XMLWordPrintableJSON

Details

    • Icon: Bug Bug
    • Resolution: Works as Designed
    • Icon: Unknown Unknown
    • None
    • 2.17.0
    • LINQ3, Serialization
    • None

    Description

      i have the following custom BsonSerializerAttribute that is used to decorate string properties of entities. the serializer implementation simply stores the property value as ObjectId if it's a valid objectid or stores it as a string if not a valid objectid. 

      [AttributeUsage(AttributeTargets.Property, AllowMultiple = false)]
      public class AsObjectIdAttribute : BsonSerializerAttribute
      {
          public AsObjectIdAttribute() : base(typeof(ObjectIdSerializer)) { }
       
          private class ObjectIdSerializer : SerializerBase<string>
          {
              public override void Serialize(BsonSerializationContext ctx, BsonSerializationArgs args, string value)
              {
                  if (value == null)
                  {
                      ctx.Writer.WriteNull(); return;
                  }
       
                  if (value.Length == 24 && ObjectId.TryParse(value, out var oID))
                  {
                      ctx.Writer.WriteObjectId(oID); return;
                  }
       
                  ctx.Writer.WriteString(value);
              }
       
              public override string Deserialize(BsonDeserializationContext ctx, BsonDeserializationArgs args)
              {
                  switch (ctx.Reader.CurrentBsonType)
                  {
                      case BsonType.String:
                          return ctx.Reader.ReadString();
       
                      case BsonType.ObjectId:
                          return ctx.Reader.ReadObjectId().ToString();
       
                      case BsonType.Null:
                          ctx.Reader.ReadNull();
                          return null;
       
                      default:
                          throw new BsonSerializationException($"'{ctx.Reader.CurrentBsonType}' values are not valid on properties decorated with an [AsObjectId] attribute!");
                  }
              }
          }
      }
      

      the following works with LinqProvider.V2 but does not work with LinqProvider.V3

      public class Person
      {
          [BsonId, AsObjectId]
          public string Id { get; set; }
       
          public string Name { get; set; }
      }
       
      var person = new Person
      {
          Id = ObjectId.GenerateNewId().ToString(),
          Name = "john doe"
      };
       
      await collection.InsertOneAsync(person);
       
      var result = await collection
          .AsQueryable()
          .Where(x => x.Id == person.Id)
          .ToListAsync();
       
      var matchesFound = result.Count > 0;
      

      i believe the underlying cause is that LINQ3 translate the filter as

      "_id" : "62d6bfac3c2e5eef721c0a14"
      

      while LINQ2 correctly translates the query to:

      "_id" : ObjectId("62d6bfac3c2e5eef721c0a14")
      

      i've also tried implelemting IBsonDocumentSerializer on the serializer but it doesn't seem to make a difference. LINQ2 does however work without implementing the interface.

      any advise would be highly appreciated in order to migrate my existing code to LINQ3.

      thanks!

      Attachments

        Activity

          People

            robert@mongodb.com Robert Stam
            djnitehawk83@gmail.com Damith G
            Votes:
            0 Vote for this issue
            Watchers:
            4 Start watching this issue

            Dates

              Created:
              Updated:
              Resolved: