【问题标题】:Error when deserialize Json .NET CORE 5 - JsonException: A possible object cycle was detected which is not supported反序列化 Json .NET CORE 5 时出错 - JsonException:检测到不支持的可能对象循环
【发布时间】:2021-08-01 22:40:55
【问题描述】:

基本上我在 .NET 5 上创建了一个 API 项目。我的想法是在 GitHub API 上获取一些存储库信息,然后在 MY API 中分配一些信息。请求成功,但是Json转为object时总是出现同样的错误

存储库控制器:

using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Logging;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Text.Json;
using System.Threading.Tasks;

[ApiController]
[Route("[controller]")]
public class RepositoriesController : ControllerBase
{
    private static readonly HttpClient client = new HttpClient();

    private readonly ILogger<RepositoriesController> _logger;

    public RepositoriesController(ILogger<RepositoriesController> logger)
    {
        _logger = logger;
    }

    [HttpGet]
    public IActionResult Get(string number)
    {
        return Ok(ProcessRepositories());
    }

    private static async Task ProcessRepositories()
    {
        client.DefaultRequestHeaders.Accept.Clear();
        client.DefaultRequestHeaders.Accept.Add(
            new MediaTypeWithQualityHeaderValue("application/vnd.github.v3+json"));
        client.DefaultRequestHeaders.Add("User-Agent", ".NET Foundation Repository Reporter");

        var streamTask = client.GetStreamAsync("https://api.github.com/orgs/dotnet/repos?sort=created&per_page=5&direction=desc");
        var repositories = await JsonSerializer.DeserializeAsync<List<Repository>>(await streamTask);
    }
}

类存储库:

 public class Repository
{
    public string full_name { get; set; }
    public string node_id { get; set; }
    //public string description { get; set; }
}

但总是在这部分:

        var repositories = await JsonSerializer.DeserializeAsync<List<Repository>>(await streamTask);

浏览器返回此错误:

JsonException:检测到可能的对象循环。这既可以 是由于循环或物体深度大于最大值 允许深度为 32。考虑使用 ReferenceHandler.Preserve on 支持循环的 JsonSerializerOptions。

我想了解为什么即使使用两个与 json 同名的简单属性也会出现错误

GitHub Api 文档 https://docs.github.com/en/rest/reference/repos

用作请求 api 基础的文档: https://docs.microsoft.com/en-us/dotnet/csharp/tutorials/console-webapiclient#deserialize-the-json-result

Github 返回的 Json(我隐藏了一些 json 的属性,因为有几个)

[
    {
        "id": 1296269,
        "node_id": "MDEwOlJlcG9zaXRvcnkxMjk2MjY5",
        "name": "Hello-World",
        "full_name": "octocat/Hello-World",
        [... several hidden properties for display purposes]
    }
]

在此先感谢 :)

【问题讨论】:

  • 在这个例子中 JSON 是什么样子的任何迹象?
  • 想知道这是否可能是因为 STJson 在 template_repository 中的 node_idfull_name 的反序列化过程中被阻塞了......跨度>
  • @MarcGravell 我用模型总结的 json 更新了问题
  • @FrankAlvaro 对不起,我不明白你的评论。它应该这样工作吗?我开始使用 API :)
  • @Jabrel - 抱歉,这更多是出于个人的好奇心:D @mj1313 的建议可能是您正在寻找的(FWIW,对于 STJson,它看起来类似于 ReferenceLoopHandling.Ignore已经被抛出以包含在 NET 5 中,但从未成功 - 也许是 NET 6?)

标签: c# json asp.net-core deserialization asp.net-core-webapi


【解决方案1】:

我建议切换到 Newtonsoft.Json 来处理循环引用问题。

1.安装NewtonsoftJson包。

Install-Package Microsoft.AspNetCore.Mvc.NewtonsoftJson

2.在ConfigureServices中添加配置。

services.AddControllers().AddNewtonsoftJson(options=>
    options.SerializerSettings.ReferenceLoopHandling = ReferenceLoopHandling.Ignore);

3.使用JsonConvert反序列化。

client.DefaultRequestHeaders.Accept.Clear();
client.DefaultRequestHeaders.Accept.Add(
    new MediaTypeWithQualityHeaderValue("application/vnd.github.v3+json"));
client.DefaultRequestHeaders.Add("User-Agent", ".NET Foundation Repository Reporter");

var streamTask = await client.GetStringAsync("https://api.github.com/orgs/dotnet/repos?sort=created&per_page=5&direction=desc");
var repositories = JsonConvert.DeserializeObject<List<Repository>>(streamTask);

【讨论】:

    猜你喜欢
    • 2021-03-17
    • 2020-03-30
    • 2020-10-02
    • 2020-05-28
    • 2020-04-27
    • 2020-07-06
    • 2021-11-19
    • 2021-12-09
    • 2021-12-03
    相关资源
    最近更新 更多