Search code examples
c#jsondeserialization.net-6.0system.text.json

How to return JSON string as an sub-object in a .NET 6 WebApi controller?


I have the following data structure which I want to return as result from a controller:

public class DataModel
{
    public string Id { get; private set; }

    public string Name { get; private set; }

    public string Description { get; private set; }

    public string ProjectId { get; private set; }

    public string Content { get; private set; }

    public DateTime CreationTime { get; private set; }

    public DateTime? LastModificationTime { get; private set; }
}

What I get in Swagger is:

{
  "id": "642af19d6d5bb761f5a62cc0",
  "name": "Test submission 8",
  "description": "test description",
  "projectId": "1a1b1c",
  "content": "{ \"Name\" : \"Test 1\", \"Id\" : \"id1\", \"Value\" : 1 }",
  "creationTime": "2023-04-03T15:32:45Z",
  "lastModificationTime": null
}

What I would like to get instead is:

{
  "id": "642af19d6d5bb761f5a62cc0",
  "name": "Test submission 8",
  "description": "test description",
  "projectId": "1a1b1c",
  "content": {
    "Name": "Test 1",
    "Id": "id1",
    "Value": 1
  },
  "creationTime": "2023-04-03T15:32:45Z",
  "lastModificationTime": null
}

Content is a JSON string. I can't create a specific kind of class and deserialize the JSON to that because the structure of the string can vary.

How can I modify the object and type of Content so Content looks like an sub-object in the JSON returned by the controller?


Solution

  • You need to return some object that will be correctly serialized. For example you can use the JsonNode API introduced in C# 6:

    public class DataModel
    {
        // ....
    
        // sample value and public setter for testing purposes:
        public JsonNode Content { get; set; } = JsonNode.Parse("""{ "Name" : "Test 1", "Id" : "id1", "Value" : 1 }""");
    
    }
    

    Another option is to create a special wrapper with custom converter which will write string as is (though in this case you either need to validate the string in converter or you can get an invalid JSON).