Search code examples
c#asp.net-web-apimongodb-.net-driver

Web API + MongoDB: list of arbitrary objects?


I have a .Net Core 2.0 Web API in which I'm using the MongoDB .net driver.

I have a class called ListOfValues:

public class ListOfValues
{
    public string ListName { get; set; }
    public List<object> MetaData { get; set; }
}

My controller's endpoint for saving is:

public class LovController : Controller
{
    [HttpPost]
    public async Task<IActionResult> Create([FromBody] ListOfValues lov)
    {
        if (!ModelState.IsValid)
            return BadRequest();

        await ldbContext.GetCollection<ListOfValues>("ListOfValues").InsertOneAsync(lov);
        return CreatedAtAction("Create", new { Id = lov.Id });
    }
}

I'm posting this data:

{
    "listName": "test",
    "MetaData": [{
        "Name": "Text",
        "FieldType": "TextBox",
        "isActive": 1
    }]
}

For some reason, when I query the DB I see this value:

{
    "_id" : ObjectId("5a1421e644d7cb07a8d3c45d"),
    "ListName" : "test",
    "MetaData" : [ 
        {
            "_t" : "Newtonsoft.Json.Linq.JObject, Newtonsoft.Json, Version=10.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed",
            "_v" : {
                "Name" : {
                    "_t" : "JValue",
                    "_v" : []
                },
                "FieldType" : {
                    "_t" : "JValue",
                    "_v" : []
                },
                "isActive" : {
                    "_t" : "JValue",
                    "_v" : []
                }
            }
        }
    ]
}

I know that if I use a list of a specified type such as class or struct it will work, but I need the list to be a dynamic object since I don't know which objects the client may send.

What do I need to do for the data saved in the DB to be readable?


Solution

  • Use Dictionary<string, object> to represent data of unknown structure.

    This works both with Newtonsoft.Json, which is the default serializer in ASP.NET Web API, and with BSON serializers of MongoDB.Driver.

    Change the ListOfValues class as follows:

    public class ListOfValues
    {
        [JsonIgnore]
        public ObjectId Id { get; set; }
    
        public string ListName { get; set; }
    
        public List<Dictionary<string,object>> MetaData { get; set; }
    }
    

    The Id property is required in order to fetch data from the DB. With JsonIgnore attribute, it won't be present in the JSON returned/received by the controller.

    Tested with:

    • ASP.NET Core 2.0 Web API
    • Newtonsoft.Json 10.0.3
    • MongoDB.Driver 2.4.4
    • MongoDB server 3.4 w/WiredTiger