JsonResult(object) 导致“不支持集合类型'Newtonsoft.Json.Linq.JToken'。”

Posted

技术标签:

【中文标题】JsonResult(object) 导致“不支持集合类型\'Newtonsoft.Json.Linq.JToken\'。”【英文标题】:JsonResult(object) causes "The collection type 'Newtonsoft.Json.Linq.JToken' is not supported."JsonResult(object) 导致“不支持集合类型'Newtonsoft.Json.Linq.JToken'。” 【发布时间】:2020-01-24 03:06:33 【问题描述】:

我将现有的 ASP.NET Core 2.2 项目升级到 3.0。我有一个返回 JSON 的方法,该方法在 2.2 中有效,但在 3.0 中,它会导致“不支持集合类型‘Newtonsoft.Json.Linq.JToken’。”在返回时。

[HttpGet()]
public async Task<JsonResult> Get()

    var res = some class object in a third-party library;
    return new JsonResult(res);

我搜索了谷歌,发现微软已经将Newtonsoft Json替换为System.Text.Json,但我并没有明确使用Newtonsoft Json。在项目的“框架”中,我可以看到 Newtonsoft Json,我删除了它和 using Newtonsoft.Json.Linq 语句,但结果是一样的。如何不使用 Newtonsoft Json?

错误信息是:

System.NotSupportedException: The collection type 'Newtonsoft.Json.Linq.JToken' is not supported.
   at System.Text.Json.JsonClassInfo.GetElementType(Type propertyType, Type parentType, MemberInfo memberInfo, JsonSerializerOptions options)
   at System.Text.Json.JsonClassInfo.CreateProperty(Type declaredPropertyType, Type runtimePropertyType, Type implementedPropertyType, PropertyInfo propertyInfo, Type parentClassType, JsonConverter converter, JsonSerializerOptions options)
   at System.Text.Json.JsonClassInfo.AddProperty(Type propertyType, PropertyInfo propertyInfo, Type classType, JsonSerializerOptions options)
   at System.Text.Json.JsonClassInfo.AddPolicyProperty(Type propertyType, JsonSerializerOptions options)
   at System.Text.Json.JsonClassInfo..ctor(Type type, JsonSerializerOptions options)
   at System.Text.Json.JsonSerializerOptions.GetOrAddClass(Type classType)
   at System.Text.Json.JsonPropertyInfo.get_ElementClassInfo()
   at System.Text.Json.JsonSerializer.HandleObject(JsonPropertyInfo jsonPropertyInfo, JsonSerializerOptions options, Utf8JsonWriter writer, WriteStack& state)
   at System.Text.Json.JsonSerializer.WriteObject(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.Infrastructure.SystemTextJsonResultExecutor.ExecuteAsync(ActionContext context, JsonResult result)
   at Microsoft.AspNetCore.Mvc.Infrastructure.SystemTextJsonResultExecutor.ExecuteAsync(ActionContext context, JsonResult result)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeResultAsync>g__Logged|21_0(ResourceInvoker invoker, IActionResult result)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeNextResultFilterAsync>g__Awaited|29_0[TFilter,TFilterAsync](ResourceInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.Rethrow(ResultExecutedContextSealed context)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.ResultNext[TFilter,TFilterAsync](State& next, Scope& scope, Object& state, Boolean& isCompleted)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.InvokeResultFilters()
--- End of stack trace from previous location where exception was thrown ---
   at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeFilterPipelineAsync>g__Awaited|19_0(ResourceInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeAsync>g__Logged|17_1(ResourceInvoker invoker)
   at Microsoft.AspNetCore.Routing.EndpointMiddleware.<Invoke>g__AwaitRequestTask|6_0(Endpoint endpoint, Task requestTask, ILogger logger)
   at Microsoft.AspNetCore.Authorization.AuthorizationMiddleware.Invoke(HttpContext context)
   at Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddleware.Invoke(HttpContext context)

PS:我已经尝试过使用其他类型并收到一些类似的集合类型的异常消息。有了这个,我搜索了谷歌并找到了this open issue on .NET Core's GitHub。 System.Text.JSon 目前似乎不完全支持集合类型,解决方法是使用旧的 Newtonsoft Json。

【问题讨论】:

【参考方案1】:

Migrate from ASP.NET Core 2.2 to 3.0

添加对 Microsoft.AspNetCore.Mvc.NewtonsoftJson 的包引用

更新 Startup.ConfigureServices 以调用 AddNewtonsoftJson: services.AddMvc().AddNewtonsoftJson();

【讨论】:

谢谢,但有什么办法不使用 Newtonsoft Json 并使用新的System.Text.Json?我想要的只是以 JSON 格式发送对象作为响应。当然,微软新的等效类也可以做到这一点,对吧?如果没有这样的功能,我会使用您的解决方案并将其标记为答案。 这似乎是新 Json 的限制(我在 OP 底部添加了详细信息)。我只是用旧的。 我别无选择,只能使用现有的 NewtonsoftJson。我已经测试过了,上面的解决方案没有任何问题。 刚刚在 .Net Core 3 上遇到了同样的错误,System.Collections.Generic.Dictionary`2[System.DateTime,System.Int32] 的“集合类型不受支持”啊好吧,回来为此向 NewtonSoft... 非常感谢您提供这个。我疯狂地寻找这个。最重要的是它有效。【参考方案2】:

@sabiland 回答帮助了我,小改动

    在 .csproj 中添加了对 NewtonsoftJson 的引用,如下所示

    在 Startup.cs 中的 ConfigureServices 方法中添加,AddMvcCore

    services.AddMvcCore()
            .AddNewtonsoftJson();
    

【讨论】:

【参考方案3】:

在基于 .NET Core 3.1 的 Web 应用程序中,如果您遇到此错误,您需要的 Nuget 包是相同的“Microsoft.AspNetCore.Mvc.NewtonsoftJson”。

Startup 类的 ConfigureServices 方法中的代码如下所示

services.AddControllersWithViews().AddNewtonsoftJson();

参考this link

【讨论】:

注意:在控制器中的使用是using Newtonsoft.Json;,如果需要using Newtonsoft.Json.Linq;(从核心2.1迁移到3.1) 我需要返回字典才能使用 ajax 查看,但出现此错误。谢谢!!!这对我有用.Net core 3.1

以上是关于JsonResult(object) 导致“不支持集合类型'Newtonsoft.Json.Linq.JToken'。”的主要内容,如果未能解决你的问题,请参考以下文章

在 JsonResult 之后不调用 Ajax 成功

解析来自 API 的动态 jsonResult 响应给出“对象不包含 X 的定义”

MVC_JsonResult类型

如何通过 Asp.Net Core 中间件的 JsonResult 响应?

Mvc重写JsonResult

SaveChanges无法处理JsonResult方法(UPDATE INFO)