【问题标题】:Deserializing complex JSON data反序列化复杂的 JSON 数据
【发布时间】:2021-12-03 07:57:52
【问题描述】:

我正在尝试反序列化我从这里得到的一些 json https://www.reddit.com/r/tf2/hot/.json?limit=10&rawjson=1,但所有带有 newtonsoft json.net 的示例都显示为简单的 json 对象。

如何将其反序列化为一个不错的对象?

【问题讨论】:

标签: c# json .net api


【解决方案1】:

您必须创建自己的对象并在反序列化中指定对象。

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

您可以使用此站点创建一个您需要的 json 格式的虚拟对象:https://json2csharp.com/

更新

用你的例子:

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

然后:

// 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; }
}

【讨论】:

    【解决方案2】:

    在快速浏览在线可用信息后。哎呀,这种格式很烦人。

    我建议您首先定义一个基本类型、每个“种类”的子类和一个 custom converter 来反序列化它们。可能看起来像这样;

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

    【讨论】:

    • 是的,哎呀哎呀 lmao
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-08-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-04-29
    • 1970-01-01
    相关资源
    最近更新 更多