Reputation: 8681
I have written an endpoint in .netcore 3.0 to return data but which ultimately throws the following error in the controller.
The error happens on line
return Ok(cityResponses);
I can see the data prior to executing this line
System.NotSupportedException: The collection type 'Newtonsoft.Json.Linq.JObject' is not supported.
at System.Text.Json.JsonPropertyInfoNotNullable`4.GetDictionaryKeyAndValueFromGenericDictionary(WriteStackFrame& writeStackFrame, String& key, Object& value)
at System.Text.Json.JsonPropertyInfo.GetDictionaryKeyAndValue(WriteStackFrame& writeStackFrame, String& key, Object& value)
at System.Text.Json.JsonSerializer.HandleDictionary(JsonClassInfo elementClassInfo, JsonSerializerOptions options, Utf8JsonWriter writer, WriteStack& state)
at System.Text.Json.JsonSerializer.Write(Utf8JsonWriter writer, Int32 originalWriterDepth, Int32 flushThreshold, JsonSerializerOptions options, WriteStack& state)
at System.Text.Json.JsonSerializer.WriteAsyncCore(Stream utf8Json, Object value, Type inputType, JsonSerializerOptions options, CancellationToken cancellationToken)
at Microsoft.AspNetCore.Mvc.Formatters.SystemTextJsonOutputFormatter.WriteResponseBodyAsync(OutputFormatterWriteContext context, Encoding selectedEncoding)
at Microsoft.AspNetCore.Mvc.Formatters.SystemTextJsonOutputFormatter.WriteResponseBodyAsync(OutputFormatterWriteContext context, Encoding selectedEncoding)
at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeResultAsync>g__Logged|21_0(ResourceInvoker invoker, IActionResult result)
Controller
[HttpGet]
[Route("cities")]
public async Task<IActionResult> Cities()
{
var cities = await _cityInfoService.GetCities();
var cityResponses = MapCityResponse(cities);
return Ok(cityResponses);
}
Upvotes: 3
Views: 6242
Reputation: 388023
The error message already gives you some hint here:
System.NotSupportedException: The collection type 'Newtonsoft.Json.Linq.JObject' is not supported. at System.Text.Json.JsonPropertyInfoNotNullable`4.GetDictionaryKeyAndValueFromGenericDictionary(WriteStackFrame& writeStackFrame, String& key, Object& value)
As you can see, there is some Newtonsoft.Json.Linq
namespace, and a System.Text.Json
namespace.
Starting with ASP.NET Core 3.0, the default serializer for JSON was changed from Newtonsoft.Json to the new serializer that is built into .NET Core: System.Text.Json. There is very detailed documentation on the differences between these two serializers and how to migrate your code to System.Text.Json. But the summary here is that System.Text.Json is—by design—more limited than Newtonsoft.Json and it will not be able to serialize directly from or to those JObject
or JArray
objects.
Fortunately, for applications that rely on the behavior of Newtonsoft.Json or otherwise require some of its flexibility, there is a way to reconfigure the ASP.NET Core application to continue using Newtonsoft.Json for JSON serialization.
To do that, you can follow the migration guide for ASP.NET Core 3.0. Essentially you will have to reference the NuGet package Microsoft.AspNetCore.Mvc.NewtonsoftJson
and then call AddNewtonsoftJson()
on the MVC builder in your ConfigureServices
method. For example:
services.AddControllers()
.AddNewtonsoftJson();
This will ensure that Newtonsoft.Json is used for all of the built-in JSON serialization, so your JObject
and JArray
usages should continue to work then.
Upvotes: 9