簡體   English   中英

在 C# 中反序列化 JSON 文件時出現 StackOverflowException

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

這是我的 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,沒有額外的細節。

問題是,您的呼叫LoadBlogPost()類的BlogPost在構造函數,然后你有一個List<BlogPost>BlogRoot 反序列化嘗試為您的 json 中的每個 blogPost-Element 創建一個新的BlogPost ,因此再次調用構造函數,該構造函數再次調用反序列化。

你有你的無限循環;-)

您可以改為刪除構造函數中的代碼並創建一個生成列表的靜態類方法:

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

也許它是你所擁有的

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

這意味着LoadBlogPost方法每次反序列化器想要創建一個BlogPost實例時BlogPost遞歸地LoadBlogPost自己...... -> Boom,堆棧溢出。

反序列化應該在對象之外。 你可以這樣做:

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