Преобразование JSON в массив пользовательских объектов - PullRequest
3 голосов
/ 17 декабря 2011

Я пытаюсь создать приложение Reddit (только для практики) для Windows Phone 7, используя C # и Json.Net. Я пытаюсь научиться преобразовывать 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.";
        });

Эта строка говорит мне, что требуется "новый" вызов.

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

1 Ответ

5 голосов
/ 17 декабря 2011

Я вижу пару проблем с тем, что у вас есть.Первый - это структура классов, в которые вы должны десериализовать данные json.Написание классов для этого вручную действительно утомительно и подвержено ошибкам, и поэтому я обычно хотел бы использовать этот сайт , чтобы подключить json и получить нужные мне классы и переименовать их по мере необходимости.Затем я пошел бы и нашел api docs для данных, чтобы заполнить пробелы в классах, которых у данных просто не было.

После этого вам нужно всего лишьдесериализовать один экземпляр класса корневых объектов, который у вас теперь есть, а не их список, что-то вроде:

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

Еще одно замечание: когда вы десериализуете свои данные, в своем кодевы в настоящее время объявляете новую локальную переменную с именем topics, которая скрывает вашу переменную-член, которая также называется topics, в этой конкретной области, и поэтому, если вы когда-нибудь осмотрите эту переменную-член, вы увидите, что она не будетданные в нем.Вы не хотите объявлять новую переменную там, вы просто хотите использовать существующую переменную-член, поэтому вместо предыдущей строки вы просто захотите сделать:

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

Или даже this.topics если вы хотите быть действительно явным и ясным о том, откуда эта переменная.

...