I am building a minimal ASP.NET Core Web API. One of my endpoints needs to return data contained in a JObject. This JObject represents a complex nested data structure. What I am finding is that the response from this endpoint loses all of the nested data from the JObject.
From what have read, I suspect this is caused by the fact that by default .NET Core uses its own Json libraries for serialisation and JObect is a Newtonsoft class, but so far I haven't discovered what the best practice is for handling this.
For example, the JObject that I am working with correctly contains all expected key-value data. Some values contain nested data themselves.
If I run .ToString()
on it this is what it looks like:
{
"key": "stringValue",
"key": "stringValue",
"key": "stringValue",
"key": {
"nestedKey": "nestedValue",
"nestedKey": "nestedValue"
},
"key": "stringValue",
"key": "stringValue"
..
}
The problem is that when I return the JObject like this:
JObject result = service.ParseToJObject(request.Message);
return TypedResults.Ok(result);
The response object looks like this - all the nested values have been lost.
{
"key1": [],
"key2": [],
"key2": [],
...
}
I can resolve this issue with the following change (converting the JObject to a string), but want to know if there is a better way to fix this at the global level. With this change the returned object correctly contains all key-value pairs.
string result = service.ParseToJObject(request.Message).ToString();
return TypedResults.Content(result, "application/json");
I've tried various suggestions off the net around setting Json serialization options on the builder (one example below), but none of these have made any difference to the return data.
builder.Services.ConfigureHttpJsonOptions(options =>
{
options.SerializerOptions.ReferenceHandler = ReferenceHandler.Preserve;
options.SerializerOptions.PropertyNameCaseInsensitive = true;
options.SerializerOptions.DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull;
options.SerializerOptions.Converters.Add(new JsonStringEnumConverter());
});
Thanks
The idiomatic way here is to just switch from using JObject
, Minimal APIs do not work with Newtonsoft's Json.NET, they work only with System.Text.Json
and this is not configurable and System.Text.Json
does not know anything about JObject
.
You have several options here:
JsonNode
API provided by the System.Text.Json
which provides similar capabilitiesSystem.Text.Json
which will handle JObject
correctly