简体   繁体   English

反序列化复杂的 JSON 数据

[英]Deserializing complex JSON data

I'm trying to deserialize some json I got from here https://www.reddit.com/r/tf2/hot/.json?limit=10&rawjson=1 but all the examples with newtonsoft json.net are shown with simple json objects.我正在尝试反序列化我从这里获得的一些 json https://www.reddit.com/r/tf2/hot/.json?limit=10&rawjson=1但所有带有 newtonsoft json.net 的示例都用简单的 json 显示对象。

How would I go about deserializing this into a nice object?我将如何将其反序列化为一个不错的对象?

You must create your own object and specify the object in the deserialization.您必须创建自己的对象并在反序列化中指定该对象。

YourNewRootClass result = 
                JsonSerializer.Deserialize<YourNewRootClass>(jsonString);

You can use this site to create a dummy object with the json format that you require: https://json2csharp.com/您可以使用此站点创建一个具有您需要的 json 格式的虚拟对象: https : //json2csharp.com/

UPDATE更新

with your example:用你的例子:

Root myDeserializedClass = JsonConvert.DeserializeObject<Root>(myJsonResponse);

and then:进而:

// Root myDeserializedClass = JsonConvert.DeserializeObject<Root>(myJsonResponse); 
public class LinkFlairRichtext
{
    public string e { get; set; }
    public string t { get; set; }
}

public class MediaEmbed
{
}

public class RedditVideo
{
    public int bitrate_kbps { get; set; }
    public string fallback_url { get; set; }
    public int height { get; set; }
    public int width { get; set; }
    public string scrubber_media_url { get; set; }
    public string dash_url { get; set; }
    public int duration { get; set; }
    public string hls_url { get; set; }
    public bool is_gif { get; set; }
    public string transcoding_status { get; set; }
}

public class SecureMedia
{
    public RedditVideo reddit_video { get; set; }
}

public class SecureMediaEmbed
{
}

public class AuthorFlairRichtext
{
    public string e { get; set; }
    public string t { get; set; }
    public string a { get; set; }
    public string u { get; set; }
}

public class Gildings
{
    public int gid_1 { get; set; }
}

public class ResizedIcon
{
    public string url { get; set; }
    public int width { get; set; }
    public int height { get; set; }
}

public class ResizedStaticIcon
{
    public string url { get; set; }
    public int width { get; set; }
    public int height { get; set; }
}

public class AllAwarding
{
    public int? giver_coin_reward { get; set; }
    public string subreddit_id { get; set; }
    public bool is_new { get; set; }
    public int days_of_drip_extension { get; set; }
    public int coin_price { get; set; }
    public string id { get; set; }
    public int? penny_donate { get; set; }
    public string award_sub_type { get; set; }
    public int coin_reward { get; set; }
    public string icon_url { get; set; }
    public int days_of_premium { get; set; }
    public object tiers_by_required_awardings { get; set; }
    public List<ResizedIcon> resized_icons { get; set; }
    public int icon_width { get; set; }
    public int static_icon_width { get; set; }
    public object start_date { get; set; }
    public bool is_enabled { get; set; }
    public object awardings_required_to_grant_benefits { get; set; }
    public string description { get; set; }
    public object end_date { get; set; }
    public int subreddit_coin_reward { get; set; }
    public int count { get; set; }
    public int static_icon_height { get; set; }
    public string name { get; set; }
    public List<ResizedStaticIcon> resized_static_icons { get; set; }
    public string icon_format { get; set; }
    public int icon_height { get; set; }
    public int? penny_price { get; set; }
    public string award_type { get; set; }
    public string static_icon_url { get; set; }
}

public class Media
{
    public RedditVideo reddit_video { get; set; }
}

public class Source
{
    public string url { get; set; }
    public int width { get; set; }
    public int height { get; set; }
}

public class Resolution
{
    public string url { get; set; }
    public int width { get; set; }
    public int height { get; set; }
}

public class Variants
{
}

public class Image
{
    public Source source { get; set; }
    public List<Resolution> resolutions { get; set; }
    public Variants variants { get; set; }
    public string id { get; set; }
}

public class Preview
{
    public List<Image> images { get; set; }
    public bool enabled { get; set; }
}

public class P
{
    public int y { get; set; }
    public int x { get; set; }
    public string u { get; set; }
}

public class S
{
    public int y { get; set; }
    public int x { get; set; }
    public string u { get; set; }
}

public class _34nbvtvyhht71
{
    public string status { get; set; }
    public string e { get; set; }
    public string m { get; set; }
    public List<P> p { get; set; }
    public S s { get; set; }
    public string id { get; set; }
}

public class Bec5guvyhht71
{
    public string status { get; set; }
    public string e { get; set; }
    public string m { get; set; }
    public List<P> p { get; set; }
    public S s { get; set; }
    public string id { get; set; }
}

public class _6bz9mhnlpet71
{
    public string status { get; set; }
    public string e { get; set; }
    public string m { get; set; }
    public List<P> p { get; set; }
    public S s { get; set; }
    public string id { get; set; }
}

public class Mgx8gqrlpet71
{
    public string status { get; set; }
    public string e { get; set; }
    public string m { get; set; }
    public List<P> p { get; set; }
    public S s { get; set; }
    public string id { get; set; }
}

public class _4eok02vlpet71
{
    public string status { get; set; }
    public string e { get; set; }
    public string m { get; set; }
    public List<P> p { get; set; }
    public S s { get; set; }
    public string id { get; set; }
}

public class _5oj0iz0jqet71
{
    public string status { get; set; }
    public string e { get; set; }
    public string m { get; set; }
    public List<P> p { get; set; }
    public S s { get; set; }
    public string id { get; set; }
}

public class _6dih3x0jqet71
{
    public string status { get; set; }
    public string e { get; set; }
    public string m { get; set; }
    public List<P> p { get; set; }
    public S s { get; set; }
    public string id { get; set; }
}

public class MediaMetadata
{
    public _34nbvtvyhht71 _34nbvtvyhht71 { get; set; }
    public Bec5guvyhht71 bec5guvyhht71 { get; set; }
    public _6bz9mhnlpet71 _6bz9mhnlpet71 { get; set; }
    public Mgx8gqrlpet71 mgx8gqrlpet71 { get; set; }
    public _4eok02vlpet71 _4eok02vlpet71 { get; set; }
    public _5oj0iz0jqet71 _5oj0iz0jqet71 { get; set; }
    public _6dih3x0jqet71 _6dih3x0jqet71 { get; set; }
}

public class Item
{
    public string caption { get; set; }
    public string media_id { get; set; }
    public int id { get; set; }
}

public class GalleryData
{
    public List<Item> items { get; set; }
}

public class Data2
{
    public object approved_at_utc { get; set; }
    public string subreddit { get; set; }
    public string selftext { get; set; }
    public string author_fullname { get; set; }
    public bool saved { get; set; }
    public object mod_reason_title { get; set; }
    public int gilded { get; set; }
    public bool clicked { get; set; }
    public string title { get; set; }
    public List<LinkFlairRichtext> link_flair_richtext { get; set; }
    public string subreddit_name_prefixed { get; set; }
    public bool hidden { get; set; }
    public int pwls { get; set; }
    public string link_flair_css_class { get; set; }
    public int downs { get; set; }
    public int? thumbnail_height { get; set; }
    public object top_awarded_type { get; set; }
    public bool hide_score { get; set; }
    public string name { get; set; }
    public bool quarantine { get; set; }
    public string link_flair_text_color { get; set; }
    public double upvote_ratio { get; set; }
    public string author_flair_background_color { get; set; }
    public string subreddit_type { get; set; }
    public int ups { get; set; }
    public int total_awards_received { get; set; }
    public MediaEmbed media_embed { get; set; }
    public int? thumbnail_width { get; set; }
    public string author_flair_template_id { get; set; }
    public bool is_original_content { get; set; }
    public List<object> user_reports { get; set; }
    public SecureMedia secure_media { get; set; }
    public bool is_reddit_media_domain { get; set; }
    public bool is_meta { get; set; }
    public object category { get; set; }
    public SecureMediaEmbed secure_media_embed { get; set; }
    public string link_flair_text { get; set; }
    public bool can_mod_post { get; set; }
    public int score { get; set; }
    public object approved_by { get; set; }
    public bool is_created_from_ads_ui { get; set; }
    public bool author_premium { get; set; }
    public string thumbnail { get; set; }
    public object edited { get; set; }
    public string author_flair_css_class { get; set; }
    public List<AuthorFlairRichtext> author_flair_richtext { get; set; }
    public Gildings gildings { get; set; }
    public object content_categories { get; set; }
    public bool is_self { get; set; }
    public object mod_note { get; set; }
    public double created { get; set; }
    public string link_flair_type { get; set; }
    public int wls { get; set; }
    public object removed_by_category { get; set; }
    public object banned_by { get; set; }
    public string author_flair_type { get; set; }
    public string domain { get; set; }
    public bool allow_live_comments { get; set; }
    public string selftext_html { get; set; }
    public object likes { get; set; }
    public object suggested_sort { get; set; }
    public object banned_at_utc { get; set; }
    public object view_count { get; set; }
    public bool archived { get; set; }
    public bool no_follow { get; set; }
    public bool is_crosspostable { get; set; }
    public bool pinned { get; set; }
    public bool over_18 { get; set; }
    public List<AllAwarding> all_awardings { get; set; }
    public List<object> awarders { get; set; }
    public bool media_only { get; set; }
    public string link_flair_template_id { get; set; }
    public bool can_gild { get; set; }
    public bool spoiler { get; set; }
    public bool locked { get; set; }
    public string author_flair_text { get; set; }
    public List<object> treatment_tags { get; set; }
    public bool visited { get; set; }
    public object removed_by { get; set; }
    public object num_reports { get; set; }
    public object distinguished { get; set; }
    public string subreddit_id { get; set; }
    public bool author_is_blocked { get; set; }
    public object mod_reason_by { get; set; }
    public object removal_reason { get; set; }
    public string link_flair_background_color { get; set; }
    public string id { get; set; }
    public bool is_robot_indexable { get; set; }
    public object report_reasons { get; set; }
    public string author { get; set; }
    public object discussion_type { get; set; }
    public int num_comments { get; set; }
    public bool send_replies { get; set; }
    public string whitelist_status { get; set; }
    public bool contest_mode { get; set; }
    public List<object> mod_reports { get; set; }
    public bool author_patreon_flair { get; set; }
    public string author_flair_text_color { get; set; }
    public string permalink { get; set; }
    public string parent_whitelist_status { get; set; }
    public bool stickied { get; set; }
    public string url { get; set; }
    public int subreddit_subscribers { get; set; }
    public double created_utc { get; set; }
    public int num_crossposts { get; set; }
    public Media media { get; set; }
    public bool is_video { get; set; }
    public string post_hint { get; set; }
    public Preview preview { get; set; }
    public string url_overridden_by_dest { get; set; }
    public bool? is_gallery { get; set; }
    public MediaMetadata media_metadata { get; set; }
    public GalleryData gallery_data { get; set; }
    public string after { get; set; }
    public int dist { get; set; }
    public string modhash { get; set; }
    public object geo_filter { get; set; }
    public List<Child> children { get; set; }
    public object before { get; set; }
}

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

public class Root
{
    public string kind { get; set; }
    public Data data { get; set; }
}

After a quick look at available information online.快速浏览网上的可用信息后。 Yikes, that format is annoying.哎呀,这种格式很烦人。

I would suggest you start by defining a base type, a subclass for each "kind" and a custom converter to deserialise them.我建议您首先定义一个基本类型、每个“种类”的子类和一个自定义转换器来反序列化它们。 Which might look something like this;可能看起来像这样;

public abstract class RedditBase {
}
public class RedditListing : RedditBase {
    public string Before { get; set; }
    public string After { get; set; }
    public List<RedditBase> Children { get; set; }
}
public class RedditConverter : JsonConverter<RedditBase>
{
    public override void WriteJson(JsonWriter writer, RedditBase value, JsonSerializer serializer)
        => throw new NotImplementedException();

    public override RedditBase ReadJson(JsonReader reader, Type objectType, RedditBase existingValue, bool hasExistingValue, JsonSerializer serializer)
    {
        var obj = JObject.Load(reader);
        var data = (JObject)obj["data"];

        switch ((string)obj["kind"])
        {
            case "Listing":
                {
                    var list = new RedditListing();
                    serializer.Populate(data.CreateReader(), list);
                    return list;
                }
            default:
                throw new NotImplementedException();
        }
    }
}

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

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