反序列化复杂的 JSON 数据
Posted
技术标签:
【中文标题】反序列化复杂的 JSON 数据【英文标题】:Deserializing complex JSON data 【发布时间】:2021-12-03 07:57:52 【问题描述】:我正在尝试反序列化我从这里得到的一些 json https://www.reddit.com/r/tf2/hot/.json?limit=10&rawjson=1,但所有带有 newtonsoft json.net 的示例都显示为简单的 json 对象。
如何将其反序列化为一个不错的对象?
【问题讨论】:
看起来他们的 api 文档 (reddit.com/dev/api/#section_listings) 根本没有描述响应... 我建议先阅读jcchouinard.com/documentation-on-reddit-apis-json & github.com/reddit-archive/reddit/wiki/JSON 或者reddit.com/r/redditdev/comments/bvd7w5/…,然后与现实世界进行比较... 【参考方案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以上是关于反序列化复杂的 JSON 数据的主要内容,如果未能解决你的问题,请参考以下文章