Sunday, October 25, 2020

[.NET core] System.NotSupportedException: The collection type 'System.Object' on 'somewhere' is not supported.

Somehow if you are using .NET core and return a object on controller, you might meet this exception.
   

  System.NotSupportedException: The collection type 'System.Object' on 'somewhere.InnerResult.Data' 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.WriteCore(Utf8JsonWriter writer, Object value, Type type, JsonSerializerOptions options)
   at System.Text.Json.JsonSerializer.WriteCore(PooledByteBufferWriter output, Object value, Type type, JsonSerializerOptions options)
   at System.Text.Json.JsonSerializer.WriteCoreString(Object value, Type type, JsonSerializerOptions options)
   at System.Text.Json.JsonSerializer.Serialize[TValue](TValue value, JsonSerializerOptions options)
   at TestWeb.Controllers.AuthController.VerifyToken(String token, Int32 tp) in C:\repos\somewhere\TestWeb\Controllers\AuthController.cs:line 51

In this project, I always return my custom result called InnerResult in API controller.
    public class InnerResult
    {
        public bool Success { get; set; } = true;
        public int Code { get; set; }
        public string Message { get; set; }
        public dynamic Data { get; set; }
    }

If the result json was this format, .NET core default can handle it.
{
    "success": true,
    "code": 0,
    "message": null,
    "data": "vfu3MF5RFlQV9dWNQCFh6iRPNxeezFaV"
}

but if some object in property, it will throw System.NotSupportedException

{
    "success": true,
    "code": 0,
    "message": null,
    "data": {
        "name": "Died"
    }
}

That's because in .NET core , they default using System.Text.Json to deal with json convert, but somehow it can't handle object in property, so......

To solve it, we can use our old friend Json.NET to save the day. (actually, using Microsoft.AspNetCore.Mvc.NewtonsoftJson)

Install-Package Microsoft.AspNetCore.Mvc.NewtonsoftJson -Version 3.1.9

If you are using .NET core 2.x , add .AddNewtonsoftJson() after your AddMVC()

services.AddMvc().AddNewtonsoftJson();

If using .NET core 3.x , add it after what you have.

services.AddControllers().AddNewtonsoftJson();
services.AddControllersWithViews().AddNewtonsoftJson();
services.AddRazorPages().AddNewtonsoftJson();

Then no more this System.NotSupportedExceptio again.



No comments:

Post a Comment