Search code examples
c#mongodbmongodb-.net-driver

Unknown discriminator value "SqlException", How to ignore discriminator on dynamic type


I have a model like below:

[BsonIgnoreExtraElements]
public class MongoDbLogModel
{
    public string Level { get; set; }

    public string RenderedMessage { get; set; }

    [BsonDateTimeOptions(Kind = DateTimeKind.Local)]
    public DateTime? Timestamp { get; set; }

    [BsonDateTimeOptions(Kind = DateTimeKind.Local)]
    public DateTime UtcTimeStamp { get; set; }

    public dynamic Properties { get; set; }

    public dynamic Exception { get; set; }
}

And here is the JSON model:

{
  "_id": { "$oid": "61a8dadd1ab0e48d55b06626" },
  "Level": "Error",
  "UtcTimeStamp": { "$date": "2021-12-02T14:40:30.436Z" },
  "MessageTemplate": {...},
  "RenderedMessage": "",
  "Properties": {...},
  "Exception": {
    "_t": "SqlException",
    "HelpLink": null,
    "Source": "Core Microsoft SqlClient Data Provider",
    "HResult": -2146232060,
    "Message": "Invalid object name 'SystemControlLogs'.",
    "StackTrace": "   at Microsoft.Data.SqlClien",
    "Data": {...}
  }
}

And here is my code to fetch log data:

var logs = await _collection
                .Find(builder)
                .Skip(count * page)
                .Limit(count)
                .SortByDescending(entry => entry.Timestamp)
                .ToListAsync();

I face Unknown discriminator value "SqlException" exception on deserializing data. Is there any way without creating a model for the Exception property, to get rid of that exception? (I tried BsonClassMap.RegisterClassMap<MongoDbLogModel>(); but had no luck).


Solution

  • you probably have a type that is checked at runtime. I think dynamic is not supported in MongoDB driver(although It has not been officially stated) and recommended solution is to use BsonDocument instead.

    Mixing Static and Dynamic Data - official documentation

    I'm not sure BsonDocument is applicable for you but this solution is the simplest one:

    [BsonIgnoreExtraElements]
    public class MongoDbLogModel
    {
        public string Level { get; set; }
    
        public string RenderedMessage { get; set; }
    
        [BsonDateTimeOptions(Kind = DateTimeKind.Local)]
        public DateTime? Timestamp { get; set; }
    
        [BsonDateTimeOptions(Kind = DateTimeKind.Local)]
        public DateTime UtcTimeStamp { get; set; }
        
        //changed line
        [BsonElement("Properties")]
        public BsonDocument Properties { get; set; }
        
        //changed line
        [BsonElement("Exception")]
        public BsonDocument Exception { get; set; }
    }
    

    Working code

    if BsonDocument doesn't Serve your purpose. you have to implement a custom serializer. something like this: Serialize dynamic data with mongodb