将JSON转换为自定义对象数组。

3
我正在尝试使用C#和Json.Net为Windows Phone 7创建一个Reddit应用程序(仅供练习)。我试图弄清楚如何将json转换为C#可以处理的内容,以及其他一些事情。我可以获取所需数据,但不确定是否使用了正确的方法。一旦我有了json数据,就无法将其转换为自定义对象。无论如何,我相信这段代码中有很多问题,因此任何帮助都将不胜感激。
以下是代码:
   public partial class MainPage : PhoneApplicationPage
    {
        string json = "";
    RootObject topic = new RootObject();
    public MainPage()
    {
        InitializeComponent();
    }
    private void Button_Click(object sender, RoutedEventArgs e)
    {
        textBlock1.Text = "Retrieving...";
        string url = @"http://www.reddit.com/r/all.json";
        HttpWebRequest hWebRequest = (HttpWebRequest)HttpWebRequest.Create(url);
        hWebRequest.Method = "GET";
        hWebRequest.BeginGetResponse(Response_Completed, hWebRequest);
    }
    public void Response_Completed(IAsyncResult result)
    {
        HttpWebRequest request = (HttpWebRequest)result.AsyncState;
        HttpWebResponse response = (HttpWebResponse)request.EndGetResponse(result);
        using (StreamReader streamReader = new StreamReader(response.GetResponseStream()))
        {
            json = streamReader.ReadToEnd();
            topic = JsonConvert.DeserializeObject<RootObject>(json);

        }
        Deployment.Current.Dispatcher.BeginInvoke(() =>
        {
            //textBlock2.Text = topic.data2.title;
            textBlock1.Text = "Done.";
        });

这行代码告诉我需要进行“new”调用。

textBlock2.Text = topic.data2.title;

现在这部分给我的麻烦。我该如何正确实例化data、data2和child?
     public class MediaEmbed
    {
    }

    public class Data2
    {
        public string domain { get; set; }
        public MediaEmbed media_embed { get; set; }
        public object levenshtein { get; set; }
        public string subreddit { get; set; }
        public string selftext_html { get; set; }
        public string selftext { get; set; }
        public object likes { get; set; }
        public bool saved { get; set; }
        public string id { get; set; }
        public bool clicked { get; set; }
        public string title { get; set; }
        public object media { get; set; }
        public int score { get; set; }
        public bool over_18 { get; set; }
        public bool hidden { get; set; }
        public string thumbnail { get; set; }
        public string subreddit_id { get; set; }
        public string author_flair_css_class { get; set; }
        public int downs { get; set; }
        public bool is_self { get; set; }
        public string permalink { get; set; }
        public string name { get; set; }
        public double created { get; set; }
        public string url { get; set; }
        public string author_flair_text { get; set; }
        public string author { get; set; }
        public double created_utc { get; set; }
        public int num_comments { get; set; }
        public int ups { get; set; }
        //public override string ToString()
        //{
        //    return title;
        //}
    }

    public class Child
    {
        public string kind { get; set; }
        public Data2 data { get; set; }
    }

    public class Data
    {
        public string modhash { get; set; }
        public Child[] children { get; set; }
        public string after { get; set; }
        public object before { get; set; }
    }

    public class RootObject
    {
        public RootObject()
        {
        }
        public string kind { get; set; }
        public Data data = new Data();
        public Data2 data2 = new Data2();
        public Child child = new Child();
    }
}

欢迎来到本站。在您的问题标题中添加[solved]标签并非必要,将某个答案标记为已采纳则是我们网站表示问题已解决的方式。 - BoltClock
抱歉,感谢提供信息。 - user731483
1个回答

6
我看到你所写的有几个问题。首先是将json数据反序列化为类的结构。手动编写这些类非常繁琐且容易出错,因此我通常喜欢使用这个网站插入json并获得所需的类并适当地重命名。然后,我会找到API文档以填补数据中缺失的类的任何空白。
之后,您只需要反序列化现在已经拥有的根对象类的单个实例,而不是它们的列表,所以可以这样做:
RootObject topics = JsonConvert.DeserializeObject<RootObject>(json);

另外需要注意的是,在反序列化数据时,你当前在代码中声明了一个新的局部变量topics,它会隐藏该特定作用域中也称为topics的成员变量,所以如果你检查该成员变量,你会发现它没有任何数据。你不想在那里声明一个新变量,你只想使用现有的成员变量,所以你应该改为:

topics = JsonConvert.DeserializeObject<RootObject>(json);

或者,如果您希望非常明确和清晰地说明变量来自何处,可以使用this.topics


谢谢回复。我已经根据您的建议更新了我的程序,情况有所改善,但我仍然遇到一些问题(这是我的错)。这些问题源于redditObject类,我将其称为RootObject。当我尝试从data2类中提取值时,它说我需要创建该类的新实例。然而,我不确定在哪里进行此操作。有什么建议吗?我会继续努力。另外,我已经使用新代码更新了原始帖子。 - user731483
你的RootObject为什么看起来是这样的?当我通过转换器运行json时,我总是得到:public class RootObject { public string kind { get; set; } public Data data { get; set; } }然后,要获取第一个项目的标题,您需要执行topic.data.children[0].title - Garrett Kiel
此外,我觉得你似乎并不清楚数据结构的构造方式。RootObject 包含一个 Data 类的实例,该实例又包含一个 Children 数组,每个 Children 代表来自 all.json 的单个主题。因此,你仍然收到了一系列主题,而不是单个主题,但它们嵌套在其他几个数据结构中。 - Garrett Kiel
我在RootClass中创建了额外的方法,原因甚至连我自己都不知道。后来我回去直接从那个美妙的json2c#转换器中重新复制了代码。现在对我来说很清楚的问题是,我忽略了children是一个数组的事实。我没有包括我想要提取数据的索引。老实说,json和c#对我来说真的很新,我不确定数据模型会是什么样子,以及如何一起使用它们。我回家后会尝试一下。看起来我只需要索引器就可以了。 - user731483
现在它可以工作了。我已经添加了索引,一切都很好。非常感谢你的帮助。顺便说一下,调用标题的行是topic.data.children[0].data.title;。将其添加到此帖子中,以防有人寻找答案。 - user731483

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接