简体   繁体   English

在 C# 中反序列化 JSON 文件时出现 StackOverflowException

[英]StackOverflowException when deserializing a JSON file in C#

Here is my Json file:这是我的 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"
    }
  ]
}

I am trying to deserialize the file into these classes:我正在尝试将文件反序列化为这些类:

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;
        }
    }
}

When I try to deserialize the Json file I get a StackOverflowException, and I have no idea why.当我尝试反序列化 Json 文件时,我得到一个 StackOverflowException,我不知道为什么。 I can't find any solutions online and I've been tearing my hair out trying to figure out what the cause is, probably something really obvious that I've completely overlooked.我在网上找不到任何解决方案,我一直在努力找出原因,这可能是我完全忽略的非常明显的事情。 Funnily enough, I can deserialize the Json to a dynamic array, but I just want to be able to deserialize to these classes.有趣的是,我可以将 Json 反序列化为动态数组,但我只想能够反序列化为这些类。 Any ideas?有任何想法吗?

Call Stack:调用堆栈:

>   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#

It's longer than this but it just repeats these lines.它比这更长,但它只是重复这些行。

Error message is literally just System.StackOverflowException, no extra details.错误消息实际上只是 System.StackOverflowException,没有额外的细节。

The problem is your calling LoadBlogPost() of your class BlogPost in the constructor and then you have a List<BlogPost> in your BlogRoot .问题是,您的呼叫LoadBlogPost()类的BlogPost在构造函数,然后你有一个List<BlogPost>BlogRoot The deseralization tries to create a new BlogPost foreach blogPost-Element in your json and therefore calls the constructor again, which calls the deserialization again.反序列化尝试为您的 json 中的每个 blogPost-Element 创建一个新的BlogPost ,因此再次调用构造函数,该构造函数再次调用反序列化。

There you have your infinite loop ;-)你有你的无限循环;-)

You could instead delete the code in your constructor and make a static class method that generates your list :您可以改为删除构造函数中的代码并创建一个生成列表的静态类方法:

    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;
        }
    }

Then call it like this:然后像这样调用它:

var blogPosts = BlogPost.LoadBlogPost(0);

Maybe its that you have也许它是你所拥有的

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

Which means LoadBlogPost method recursively cals itself each time deserializer wants to create an instance of BlogPost ... -> Boom, stack overflow.这意味着LoadBlogPost方法每次反序列化器想要创建一个BlogPost实例时BlogPost递归地LoadBlogPost自己...... -> Boom,堆栈溢出。

De-serialization should be outside of the object.反序列化应该在对象之外。 you can do something like this:你可以这样做:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM