C# JSON 对象不会反序列化
Posted
技术标签:
【中文标题】C# JSON 对象不会反序列化【英文标题】:C# JSON Object wont deserialize 【发布时间】:2014-01-28 20:21:41 【问题描述】:所以我已经能够为一些事情获取 JSON 对象,但是这个对象要复杂得多。
我正在尝试从 Reddit 获取 cmets。 这是我使用的方法:
public async Task<List<string>> GetComments(string currentSubreddit, string topicID)
string commentUrl = "http://www.reddit.com/r/" + currentSubreddit + "/comments/" + topicID + "/.json";
List<Comments> commentList = new List<Comments>();
string jsonText = await wc.GetJsonText(commentUrl);
Comments.RootObject deserializeObject = Newtonsoft.Json.JsonConvert.DeserializeObject<Comments.RootObject>(jsonText);
List<string> commentListTest = new List<string>();
//List<string> commentListTest = deserializeObject.data.children[0].data.children;
return commentListTest;
这是 GetJsonText 方法:
public async Task<string> GetJsonText(string url)
var request = WebRequest.Create(url);
string text;
request.ContentType = "application/json; charset=utf-8";
var response = (HttpWebResponse)await request.GetResponseAsync();
using (var sr = new StreamReader(response.GetResponseStream()))
text = sr.ReadToEnd();
return text;
这里是对象的链接:http://pastebin.com/WQ8XXGNA 以及指向 jsonText 的链接:http://pastebin.com/7Kh6cA9a
返回的错误是这样的:
“Newtonsoft.Json.JsonSerializationException”类型的异常发生在 mscorlib.dll 中,但未在用户代码中处理
附加信息:无法将当前 JSON 数组(例如 [1,2,3])反序列化为类型 'JuicyReddit.Comments+RootObject',因为该类型需要 JSON 对象(例如 "name":"value")正确反序列化。
如果有人能帮助我找出问题所在,我将不胜感激。 谢谢
【问题讨论】:
你从哪里得到这个 json 数据?认为您发布的 json 字符串无效。 @Jim 我得到这个 url 并在 GetJsonText www.reddit.com/r/AskReddit/cmets/1ut6xc/.json 中使用它 这里解释了额外的错误***.com/questions/17762032/… @Jim 你知道如何在我使用 Newtonsoft 的情况下做到这一点吗?仍然不确定如何解决它。 我为你添加了示例代码 【参考方案1】:实际上你的代码有一些问题
public async Task<List<string>> GetComments(string currentSubreddit, string topicID)
这里你不需要返回一个字符串列表,你需要返回一个完整的对象
首先将模型中的 RootObject 重命名为适当的名称,例如“CommentsObject”
所以像这样设置你的类并将其命名为 CommentsObject.cs:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace YOURNAMESPACE.Comments
public class MediaEmbed
public class SecureMediaEmbed
public class Data4
public int count get; set;
public string parent_id get; set;
public List<string> children get; set;
public string name get; set;
public string id get; set;
public string subreddit_id get; set;
public object banned_by get; set;
public string subreddit get; set;
public object likes get; set;
public object replies get; set;
public bool? saved get; set;
public int? gilded get; set;
public string author get; set;
public object approved_by get; set;
public string body get; set;
public object edited get; set;
public object author_flair_css_class get; set;
public int? downs get; set;
public string body_html get; set;
public string link_id get; set;
public bool? score_hidden get; set;
public double? created get; set;
public object author_flair_text get; set;
public double? created_utc get; set;
public object distinguished get; set;
public object num_reports get; set;
public int? ups get; set;
public class Child2
public string kind get; set;
public Data4 data get; set;
public class Data3
public string modhash get; set;
public List<Child2> children get; set;
public object after get; set;
public object before get; set;
public class Replies
public string kind get; set;
public Data3 data get; set;
public class Data2
public string domain get; set;
public object banned_by get; set;
public MediaEmbed media_embed get; set;
public string subreddit get; set;
public object selftext_html get; set;
public string selftext get; set;
public object likes get; set;
public object secure_media get; set;
public object link_flair_text get; set;
public string id get; set;
public SecureMediaEmbed secure_media_embed get; set;
public bool clicked get; set;
public bool stickied get; set;
public string author get; set;
public object media get; set;
public int score get; set;
public object approved_by 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 object edited get; set;
public object link_flair_css_class get; set;
public object author_flair_css_class get; set;
public int downs get; set;
public bool saved 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 object author_flair_text get; set;
public string title get; set;
public double created_utc get; set;
public int ups get; set;
public int num_comments get; set;
public bool visited get; set;
public object num_reports get; set;
public object distinguished get; set;
public Replies replies get; set;
public int? gilded get; set;
public string parent_id get; set;
public string body get; set;
public string body_html get; set;
public string link_id get; set;
public bool? score_hidden get; set;
public int? count get; set;
public List<string> children get; set;
public class Child
public string kind get; set;
public Data2 data get; set;
public class Data
public string modhash get; set;
public List<Child> children get; set;
public object after get; set;
public object before get; set;
public class CommentsObject
public string kind get; set;
public Data data get; set;
让你的命名空间正确!
然后处理请求并反序列化为commentobjects列表:(如果你愿意,你可以使用webclient而不是httpclient,这只是一个例子)
private HttpClient client;
public async Task<List<CommentsObject>> GetComments()
client = new HttpClient();
var response = await client.GetAsync("http://www.reddit.com/r/AskReddit/comments/1ut6xc.json");
if (response.IsSuccessStatusCode)
string json = await response.Content.ReadAsStringAsync();
List<CommentsObject> comments = await JsonConvert.DeserializeObjectAsync<List<CommentsObject>>(json);
return comments;
else
throw new Exception("Errorhandling message");
【讨论】:
感谢您的深入回应,非常感谢。我带来的一个错误是命名空间。当我尝试为 GetComments() 方法执行这并不理想(也不是完全的答案,而是更多的解决方法),但我创建了模拟 reddit 响应 json 的模型,以使反序列化超级容易。我在模型属性上使用 JsonProperty 属性来美化模型。
Here are the models
由于我的模型直接模拟了 json,我可以使用 json.net 的通用反序列化方法。
【讨论】:
我将如何使用 Newtonsoft 插件。有点困惑它是如何工作的 S: 假设我执行了对 reddit.com/r/all.json 的访问,Reddit 为您提供了一个“列表”。我用ListingModel 模拟了listing json。要获得强类型的ListingModel,我所要做的就是: var listing = JsonConvert.DeserializeObject(response) 其中 response 是 json。由于 ListingModel 及其子代模拟了返回的 json,它只是将 json 中的属性名称与我的模型匹配。如果您想了解它是如何使用的,请查看该 repo 中的测试控制台项目。 感谢您的回复。我会看看你在说什么,并尝试让它发挥作用:)以上是关于C# JSON 对象不会反序列化的主要内容,如果未能解决你的问题,请参考以下文章