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

StackoverflowException deserializing Dictionary<string, Interface>

    • Type: Icon: Bug Bug
    • Resolution: Done
    • Priority: Icon: Major - P3 Major - P3
    • 1.9.1
    • Affects Version/s: 1.8.3, 1.9
    • Component/s: Serialization
    • None

      Experienced

      When deserializing a class that has a property defines as Dictionary<string, Interface> a StackoverFlow exception will be thrown in mscorlib.dll.

      If the property is changed to Dictionary<string, Concrete> the issue does not occur.

      Expected

      Interface deserialization on Dictionary properties where the value is an interface type should work.

      Reproduction

      Console Main

      static void Main(string[] args)
      {
      
          var client = new MongoClient();
          var server = client.GetServer();
          var db = server.GetDatabase("test");
          var collection = db.GetCollection("ParentChildren");
          BsonClassMap.RegisterClassMap<Parent>();
          BsonClassMap.RegisterClassMap<Child>();
      
          var parents = collection.FindAllAs<Parent>();
      
                  
          foreach (var parent in parents)
          {
              Console.Out.WriteLine(parent.Name);
      
              foreach (var keyValuePair in parent.StringToChildren)
              {
                  var child = keyValuePair.Value;
                  Console.Out.WriteLine("Key: "+ keyValuePair.Key +" Name: " + child.Name);
              }
          }
      
          Console.Out.WriteLine("Press Enter to exit");
          Console.ReadLine();
      }
      

      Interfaces

      public interface IParent
      {
          [BsonId]
          BsonObjectId Id { get; set; }
      
          [BsonElement("name")]
          string Name { get; set; }
      
          [BsonElement("children")]
          Dictionary<string, IChild> StringToChildren { get; set; }
          //above is the issue, changing IChild to Child here and in the
          //concrete works around the issue.
      }
      
      
      public interface IChild
      {
          [BsonElement("name")]
          string Name { get; set; }
      }
      

      Concretes

      public class Parent : IParent
      {
          [BsonId]
          public BsonObjectId Id { get; set; }
      
          [BsonElement("name")]
          public string Name { get; set; }
      
          [BsonElement("children")]
          public Dictionary<string, IChild> StringToChildren { get; set; }
      }
      
      public class Child: IChild
      {
          [BsonElement("name")]
          public string Name { get; set; }
      }
      

      Example Document

      {
          "_id" : ObjectId("535a524abfcae300b04cea7b"),
          "name" : "ParentName",
          "children" : {
              "one" : {
                  "name" : "bob"
              },
              "two" : {
                  "name" : "jane"
              }
          }
      }
      

            Assignee:
            robert@mongodb.com Robert Stam
            Reporter:
            andrewpmartinez Andrew Martinez
            Votes:
            0 Vote for this issue
            Watchers:
            2 Start watching this issue

              Created:
              Updated:
              Resolved: