1

Here is my Json file:

{
  "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": "[email protected]",
          "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": "[email protected]",
          "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": "[email protected]",
          "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. 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. 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.

5
  • how much data you are trying to Deserialize? Commented Aug 25, 2020 at 9:50
  • What's the exact error, what does the call stack show? Is the stack just from DeserializeObject and then into the JSON.NET lib? Commented Aug 25, 2020 at 9:53
  • stackoverflow.com/questions/39980162/… found something similar. Commented Aug 25, 2020 at 9:55
  • Put a breakpoint into LoadBlogPost and see what is going on. You'll be surprised. Commented Aug 25, 2020 at 10:00
  • See, how it goes back and forth between the two lines? That's an indication that one is calling the other. Each time, a little bit of memory is being consumed from the stack until there is no more stack available. Guess what happens then? ;) Commented Aug 25, 2020 at 10:05

3 Answers 3

3

The problem is your calling LoadBlogPost() of your class BlogPost in the constructor and then you have a List<BlogPost> in your 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.

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);
Sign up to request clarification or add additional context in comments.

2 Comments

OP: You can completely omit the id, btw. It's unused.
This has really helped me, thanks! I can completely see how I was creating the infinite loop now. I'd confused myself into thinking I needed to initialise the BlogPost by deserializing it in the constructor and then setting the properties, without thinking that the deserializer would just set all the properties for me.
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.

Comments

0

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();

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.