【问题标题】:StackOverflowException when deserializing a JSON file in C#在 C# 中反序列化 JSON 文件时出现 StackOverflowException
【发布时间】:2020-08-25 18:14:06
【问题描述】:

这是我的 Json 文件:

{
  "blogPosts": [
    {
      "id": 1,
      "date": "2019-11-11T18:11:22.511Z",
      "title": "title1",
      "image": "https://www.imageExample.com/static/ae8188adb9e0f13c40fce50bd773bc51/a6b7d/Content-considerations.jpg",
      "htmlContent": "htmlExample",
      "comments": [
        {
          "name": "Joe Bloggs",
          "date": "2019-11-11T20:44:01.000Z",
          "emailAddress": "joeblogs@mailinator.co.uk",
          "message": "Sed vel odio consequat, elementum massa quis, lobortis est. Nulla egestas congue dolor, sit amet fermentum massa dignissim sit amet. In vestibulum iaculis egestas."
        },
        {
          "name": "John Smith",
          "date": "2019-11-13T09:00:23.533Z",
          "emailAddress": "johnsmith@mailinator.co.uk",
          "message": "Nam vel aliquet nulla, ac tempor ex. Suspendisse sit amet sollicitudin ex, vel placerat ipsum. Duis vitae fermentum eros. In maximus maximus purus, et volutpat eros rutrum et. Nulla fringilla at massa vel varius. In tristique egestas nisl, vitae elementum orci fringilla quis. Ut rutrum mauris erat, a rhoncus orci posuere non. Orci varius natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus."
        },
        {
          "name": "Jack Black",
          "date": "2019-11-11T19:22:22.511Z",
          "emailAddress": "jackblack@mailinator.co.uk",
          "message": "Integer volutpat, sapien eu dapibus sodales, ipsum arcu dapibus elit, ac faucibus mi ligula suscipit mauris."
        }
      ]
    },
    {
      "id": 2,
      "date": "2019-11-01T01:21:39.123Z",
      "title": "title2",
      "image": "https://www.imageExample.com/static/251940c537d045417ef75286eb970948/f9a6c/Ben.jpg",
      "htmlContent": "htmlExample"
    },
    {
      "id": 3,
      "date": "2019-10-28T14:53:09.511Z",
      "title": "title3",
      "image": "https://www.imageExample.com/static/026bfc5011b0f64f2b912fd1d0ef87ae/f9a6c/brno.jpg",
      "htmlContent": "htmlExample"
    }
  ]
}

我正在尝试将文件反序列化为这些类:

public class BlogRoot
{
    [JsonProperty("blogPosts")]
    public List<BlogPost> BlogPosts {get;set;}
}

public class Comment
{
    [JsonProperty("name")]
    public string Name { get; set; }

    [JsonProperty("date")]
    public DateTime Date { get; set; }

    [JsonProperty("emailAddress")]
    public string EmailAddress { get; set; }

    [JsonProperty("message")]
    public string Message { get; set; }
}

public class BlogPost
{
    [JsonProperty("id")]
    public int Id { get; set; }

    [JsonProperty("date")]
    public DateTime Date { get; set; }

    [JsonProperty("title")]
    public string Title { get; set; }

    [JsonProperty("image")]
    public Uri Image { get; set; }

    [JsonProperty("htmlContent")]
    public string HtmlContent { get; set; }

    [JsonProperty("comments", NullValueHandling = NullValueHandling.Ignore)]
    public List<Comment> Comments { get; set; }

    public BlogPost(int id)
    {
        LoadBlogPost(id);
    }

    private List<BlogPost> LoadBlogPost(int id)
    {
        string path = HostingEnvironment.MapPath(@"~\App_Data\Blog-Posts - Copy.json");
        string jsonFromFile;
        using (StreamReader reader = File.OpenText(path))
        {
            jsonFromFile = reader.ReadToEnd();

            var root = JsonConvert.DeserializeObject<BlogRoot>(jsonFromFile);

            return root.BlogPosts;
        }
    }
}

当我尝试反序列化 Json 文件时,我得到一个 StackOverflowException,我不知道为什么。我在网上找不到任何解决方案,我一直在努力找出原因,这可能是我完全忽略的非常明显的事情。有趣的是,我可以将 Json 反序列化为动态数组,但我只想能够反序列化为这些类。有什么想法吗?

调用堆栈:

>   Web.dll!Web.Business.BlogPost.LoadBlogPost(int id) Line 39  C#
Web.dll!Web.Business.BlogPost.BlogPost(int id) Line 34  C#
[External Code] 
Web.dll!Web.Business.BlogPost.LoadBlogPost(int id) Line 47  C#
Web.dll!Web.Business.BlogPost.BlogPost(int id) Line 34  C#
[External Code] 
Web.dll!Web.Business.BlogPost.LoadBlogPost(int id) Line 47  C#
Web.dll!Web.Business.BlogPost.BlogPost(int id) Line 34  C#
[External Code] 
Web.dll!Web.Business.BlogPost.LoadBlogPost(int id) Line 47  C#
Web.dll!Web.Business.BlogPost.BlogPost(int id) Line 34  C#
[External Code] 
Web.dll!Web.Business.BlogPost.LoadBlogPost(int id) Line 47  C#

它比这更长,但它只是重复这些行。

错误消息实际上只是 System.StackOverflowException,没有额外的细节。

【问题讨论】:

  • 您要反序列化多少数据?
  • 确切的错误是什么,调用堆栈显示什么?堆栈是否只是来自DeserializeObject,然后进入 JSON.NET 库?
  • stackoverflow.com/questions/39980162/… 发现了类似的东西。
  • LoadBlogPost 中放一个断点,看看发生了什么。你会感到惊讶。
  • 看看,它是如何在两条线之间来回移动的?这表明一个人正在呼叫另一个人。每次,都会从堆栈中消耗一点内存,直到没有更多可用的堆栈为止。猜猜接下来会发生什么? ;)

标签: c# json


【解决方案1】:

问题是你在构造函数中调用你的类BlogPostLoadBlogPost(),然后你的BlogRoot 中有一个List&lt;BlogPost&gt;。 反序列化尝试在您的 json 中创建一个新的 BlogPost foreach blogPost-Element 并因此再次调用构造函数,该构造函数再次调用反序列化。

你有你的无限循环;-)

您可以改为删除构造函数中的代码并创建一个静态类方法来生成您的列表:

    public BlogPost()
    {
    }

    public static  List<BlogPost> LoadBlogPost(int id)
    {
        string path = "my.xml";
        string jsonFromFile;
        using (StreamReader reader = File.OpenText(path))
        {
            jsonFromFile = reader.ReadToEnd();

            var root = JsonConvert.DeserializeObject<BlogRoot>(jsonFromFile);

            return root.BlogPosts;
        }
    }

然后这样称呼它:

var blogPosts = BlogPost.LoadBlogPost(0);

【讨论】:

  • OP:您可以完全省略 id,顺便说一句。没用过。
  • 这对我很有帮助,谢谢!我现在可以完全看到我是如何创建无限循环的。我困惑地认为我需要通过在构造函数中反序列化它然后设置属性来初始化 BlogPost,而没有想到反序列化器只会为我设置所有属性。
【解决方案2】:

也许你有

public BlogPost(int id)
{
    LoadBlogPost(id);  // <-- problem...
}

这意味着每次反序列化器想要创建BlogPost 的实例时,LoadBlogPost 方法都会递归地调用自己... -> 砰,堆栈溢出。

【讨论】:

    【解决方案3】:

    反序列化应该在对象之外。你可以这样做:

    var json = File.ReadAllText("json1.json");
    var root = JsonConvert.DeserializeObject<BlogRoot>(json);
    var blog = root.BlogPosts.Where(b => b.Id == 1).FirstOrDefault();
    

    【讨论】:

      猜你喜欢
      • 2020-12-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-11-14
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多