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

StackOverflowException when serializing a class C that implements IEnumerable<C>

    XMLWordPrintable

    Details

    • Type: Bug
    • Status: Closed
    • Priority: Minor - P4
    • Resolution: Fixed
    • Affects Version/s: None
    • Fix Version/s: 2.1
    • Component/s: Serialization
    • Labels:
      None
    • Sprint:
      C# Sprint 20

      Description

      If the object that is being inserted has a dynamic type with a JObject type in it (this is the default type used by JSON.NET for deserialize the JSON), then the InsertOneAsync method throws the StackOverflowException.

      It would be OK if driver does not support JObject and throws an appropriate exception, but since the StackOverflowException crashes the application and is very hard to debug, at very least the driver should not cause this type of exception.

      This is the code to replicate it:

      async Task Main()
      {
      string msg = @"

      { ""PayrollId"":463236,""Message"":""Fine"",""Success"":true,""MessageCode"":200,""IsError"":false }

      ";
      dynamic details = Newtonsoft.Json.JsonConvert.DeserializeObject(msg);

      var data = new DomainEventData()

      { AggregateId = Guid.NewGuid(), TenantId = Guid.NewGuid(), AggregateName = "Just a test", EventName = "payrollunit-schedule-missed", Details = details }

      ;

      MongoClient client = new MongoClient("mongodb://localhost/tests");
      IMongoDatabase mongo = client.GetDatabase("tests");
      IMongoCollection<DomainEventData> items = mongo.GetCollection<DomainEventData>("entries");

      await items.InsertOneAsync(data);
      }

      // Define other methods and classes here
      [Serializable]
      public class DomainEventData
      {
      public Guid Id

      { get; set; }
      [BsonElement("eventName")]
      public string EventName { get; set; }

      [BsonElement("tenantId")]
      public Guid TenantId

      { get; set; }
      [BsonElement("aggregateId")]
      public Guid AggregateId { get; set; }

      [BsonElement("aggregateName")]
      public string AggregateName

      { get; set; }
      [BsonElement("details")]
      public dynamic Details { get; set; }

      [BsonElement("utcTimestamp")]
      [BsonDateTimeOptions(Kind = DateTimeKind.Utc)]
      public DateTime UtcTimestamp

      { get; set; }

      public DomainEventData()

      { this.Id = Guid.NewGuid(); this.TenantId = Guid.Empty; this.AggregateId = Guid.Empty; this.EventName = string.Empty; this.UtcTimestamp = DateTime.UtcNow; this.AggregateName = string.Empty; }

      }

      BTW, changing the:
      dynamic details = Newtonsoft.Json.JsonConvert.DeserializeObject(msg);
      to:
      dynamic details = Newtonsoft.Json.JsonConvert.DeserializeObject<ExpandoObject>(msg);
      solves the issue, but if application is dealing with unknown data coming in, this might not be an option.

        Attachments

          Issue Links

            Activity

              People

              Assignee:
              rstam Robert Stam
              Reporter:
              lennygran Lenny Granovsky
              Participants:
              Votes:
              0 Vote for this issue
              Watchers:
              2 Start watching this issue

                Dates

                Created:
                Updated:
                Resolved: