从 json 转换的 C# 问题
C# Issue with converting from json
我想从 WordPress 测试站点获取帖子。当我调试时,我可以看到我从 Web 获取数据,但是当我尝试将它们放入 TextBox 时,它们似乎不存在。我使用网站从 C# 创建 类,但我认为问题出在我的代码中。我这样调用方法:
RootObject myPosts = await Class1.Get();
然后,为了向用户显示值,我这样做:
textBox1.Text = myPosts.id + " - " + myPosts.author+ "-" + myPosts.title;
代码:
public class Class1
{
public async static Task<RootObject> Get()
{
var http = new HttpClient();
var response = await http.GetAsync("http://bearlike-attackers.000webhostapp.com/wp-json/wp/v2/posts?search=TEST");
var result = await response.Content.ReadAsStringAsync();
var serializer = new DataContractJsonSerializer(typeof(RootObject));
var ms = new MemoryStream(Encoding.UTF8.GetBytes(result));
var data = (RootObject)serializer.ReadObject(ms);
return data;
}
}
[DataContract]
public class Guid
{
[DataMember]
public string rendered { get; set; }
}
[DataContract]
public class Title
{
[DataMember]
public string title { get; set; }
}
[DataContract]
public class Content
{
[DataMember]
public string rendered { get; set; }
[DataMember]
public bool @protected { get; set; }
}
[DataContract]
public class Excerpt
{
[DataMember]
public string rendered { get; set; }
[DataMember]
public bool @protected { get; set; }
}
[DataContract]
public class Self
{
[DataMember]
public string href { get; set; }
}
[DataContract]
public class Collection
{
[DataMember]
public string href { get; set; }
}
[DataContract]
public class About
{
[DataMember]
public string href { get; set; }
}
[DataContract]
public class Author
{
[DataMember]
public bool embeddable { get; set; }
[DataMember]
public string href { get; set; }
}
[DataContract]
public class Reply
{
[DataMember]
public bool embeddable { get; set; }
[DataMember]
public string href { get; set; }
}
[DataContract]
public class VersionHistory
{
[DataMember]
public string href { get; set; }
}
[DataContract]
public class WpAttachment
{
[DataMember]
public string href { get; set; }
}
[DataContract]
public class WpTerm
{
[DataMember]
public string taxonomy { get; set; }
[DataMember]
public bool embeddable { get; set; }
[DataMember]
public string href { get; set; }
}
[DataContract]
public class Cury
{
[DataMember]
public string name { get; set; }
[DataMember]
public string href { get; set; }
[DataMember]
public bool templated { get; set; }
}
/*
public class Links
{
public List<Self> self { get; set; }
public List<Collection> collection { get; set; }
public List<About> about { get; set; }
public List<Author> author { get; set; }
public List<Reply> replies { get; set; }
public List<VersionHistory> __invalid_name__version-history { get; set; }
public List<WpAttachment> __invalid_name__wp:attachment { get; set; }
public List<WpTerm> __invalid_name__wp:term { get; set; }
public List<Cury> curies { get; set; }
}
*/
[DataContract]
public class RootObject
{
[DataMember]
public string date { get; set; }
[DataMember]
public int id { get; set; }
[DataMember]
public string date_gmt { get; set; }
[DataMember]
public Guid guid { get; set; }
[DataMember]
public string modified { get; set; }
[DataMember]
public string modified_gmt { get; set; }
[DataMember]
public string slug { get; set; }
[DataMember]
public string type { get; set; }
[DataMember]
public string link { get; set; }
[DataMember]
public Title title { get; set; }
[DataMember]
public Content content { get; set; }
[DataMember]
public Excerpt excerpt { get; set; }
[DataMember]
public int author { get; set; }
[DataMember]
public int featured_media { get; set; }
[DataMember]
public string comment_status { get; set; }
[DataMember]
public string ping_status { get; set; }
[DataMember]
public bool sticky { get; set; }
[DataMember]
public string template { get; set; }
[DataMember]
public string format { get; set; }
/*
[DataMember]
public List<object> meta { get; set; }
[DataMember]
public List<int> categories { get; set; }
[DataMember]
public List<object> tags { get; set; }
[DataMember]
public Links _links { get; set; }
*/
}
}
如果您将 URL 粘贴到 http://jsonlint.com/,您将看到格式化后的 JSON 如下所示:
[{
"id": 4,
"date": "2017-02-16T14:28:41",
"date_gmt": "2017-02-16T13:28:41",
"guid": {
"rendered": "https:\/\/bearlike-attackers.000webhostapp.com\/?p=4"
},
"modified": "2017-02-16T14:28:41",
"modified_gmt": "2017-02-16T13:28:41",
"slug": "testy",
"type": "post",
"link": "https:\/\/bearlike-attackers.000webhostapp.com\/2017\/02\/16\/testy\/",
"title": {
"rendered": "Testy"
},
// And many other properties.
}]
注意到外面的 [
和 ]
了吗?您的问题是您的外部 JSON 容器是一个数组,而不是 object。如 JSON standard 中所述:
数组是有序的 collection 值。数组以 [
(左括号)开始,以 ]
(右括号)结束。值由 ,
(逗号)分隔。
object 是 name/value 对的无序集合。 object 以 {
(左大括号)开始,以 }
(右大括号)结束。
DataContractJsonSerializer
将 JSON 数组序列化为 .Net collection 类型,例如 List<T>
和 T []
。因此,您必须按如下方式反序列化:
public async static Task<List<RootObject>> Get()
{
var http = new HttpClient();
var response = await http.GetAsync("http://bearlike-attackers.000webhostapp.com/wp-json/wp/v2/posts?search=TEST");
var result = await response.Content.ReadAsStringAsync();
var serializer = new DataContractJsonSerializer(typeof(List<RootObject>));
var ms = new MemoryStream(Encoding.UTF8.GetBytes(result));
var list = (List<RootObject>)serializer.ReadObject(ms);
return list;
}
如果您确定您的服务只会 return 一项,您可以使用 Enumerable.SingleOrDefault()
:
return 一项 RootObject
return list.SingleOrDefault();
让我有点惊讶的是DataContractJsonSerializer
在这种情况下默默地什么都不做。 json.net throws an Unexpected token: StartArray
这种情况例外。
最后,用于标题的 属性 名称是 "rendered"
而不是 "title"
。因此你的 Title
class 需要看起来像:
[DataContract]
public class Title
{
[DataMember]
public string rendered { get; set; }
}
要访问它的值,请执行(根据需要添加任何空检查):
var s = myPost.id + " - " + myPost.author + "-" + myPost.title.rendered;
(我还没有检查你的其他数据合同成员名称的正确性。你应该检查,因为有一个不正确。)
我想从 WordPress 测试站点获取帖子。当我调试时,我可以看到我从 Web 获取数据,但是当我尝试将它们放入 TextBox 时,它们似乎不存在。我使用网站从 C# 创建 类,但我认为问题出在我的代码中。我这样调用方法:
RootObject myPosts = await Class1.Get();
然后,为了向用户显示值,我这样做:
textBox1.Text = myPosts.id + " - " + myPosts.author+ "-" + myPosts.title;
代码:
public class Class1
{
public async static Task<RootObject> Get()
{
var http = new HttpClient();
var response = await http.GetAsync("http://bearlike-attackers.000webhostapp.com/wp-json/wp/v2/posts?search=TEST");
var result = await response.Content.ReadAsStringAsync();
var serializer = new DataContractJsonSerializer(typeof(RootObject));
var ms = new MemoryStream(Encoding.UTF8.GetBytes(result));
var data = (RootObject)serializer.ReadObject(ms);
return data;
}
}
[DataContract]
public class Guid
{
[DataMember]
public string rendered { get; set; }
}
[DataContract]
public class Title
{
[DataMember]
public string title { get; set; }
}
[DataContract]
public class Content
{
[DataMember]
public string rendered { get; set; }
[DataMember]
public bool @protected { get; set; }
}
[DataContract]
public class Excerpt
{
[DataMember]
public string rendered { get; set; }
[DataMember]
public bool @protected { get; set; }
}
[DataContract]
public class Self
{
[DataMember]
public string href { get; set; }
}
[DataContract]
public class Collection
{
[DataMember]
public string href { get; set; }
}
[DataContract]
public class About
{
[DataMember]
public string href { get; set; }
}
[DataContract]
public class Author
{
[DataMember]
public bool embeddable { get; set; }
[DataMember]
public string href { get; set; }
}
[DataContract]
public class Reply
{
[DataMember]
public bool embeddable { get; set; }
[DataMember]
public string href { get; set; }
}
[DataContract]
public class VersionHistory
{
[DataMember]
public string href { get; set; }
}
[DataContract]
public class WpAttachment
{
[DataMember]
public string href { get; set; }
}
[DataContract]
public class WpTerm
{
[DataMember]
public string taxonomy { get; set; }
[DataMember]
public bool embeddable { get; set; }
[DataMember]
public string href { get; set; }
}
[DataContract]
public class Cury
{
[DataMember]
public string name { get; set; }
[DataMember]
public string href { get; set; }
[DataMember]
public bool templated { get; set; }
}
/*
public class Links
{
public List<Self> self { get; set; }
public List<Collection> collection { get; set; }
public List<About> about { get; set; }
public List<Author> author { get; set; }
public List<Reply> replies { get; set; }
public List<VersionHistory> __invalid_name__version-history { get; set; }
public List<WpAttachment> __invalid_name__wp:attachment { get; set; }
public List<WpTerm> __invalid_name__wp:term { get; set; }
public List<Cury> curies { get; set; }
}
*/
[DataContract]
public class RootObject
{
[DataMember]
public string date { get; set; }
[DataMember]
public int id { get; set; }
[DataMember]
public string date_gmt { get; set; }
[DataMember]
public Guid guid { get; set; }
[DataMember]
public string modified { get; set; }
[DataMember]
public string modified_gmt { get; set; }
[DataMember]
public string slug { get; set; }
[DataMember]
public string type { get; set; }
[DataMember]
public string link { get; set; }
[DataMember]
public Title title { get; set; }
[DataMember]
public Content content { get; set; }
[DataMember]
public Excerpt excerpt { get; set; }
[DataMember]
public int author { get; set; }
[DataMember]
public int featured_media { get; set; }
[DataMember]
public string comment_status { get; set; }
[DataMember]
public string ping_status { get; set; }
[DataMember]
public bool sticky { get; set; }
[DataMember]
public string template { get; set; }
[DataMember]
public string format { get; set; }
/*
[DataMember]
public List<object> meta { get; set; }
[DataMember]
public List<int> categories { get; set; }
[DataMember]
public List<object> tags { get; set; }
[DataMember]
public Links _links { get; set; }
*/
}
}
如果您将 URL 粘贴到 http://jsonlint.com/,您将看到格式化后的 JSON 如下所示:
[{
"id": 4,
"date": "2017-02-16T14:28:41",
"date_gmt": "2017-02-16T13:28:41",
"guid": {
"rendered": "https:\/\/bearlike-attackers.000webhostapp.com\/?p=4"
},
"modified": "2017-02-16T14:28:41",
"modified_gmt": "2017-02-16T13:28:41",
"slug": "testy",
"type": "post",
"link": "https:\/\/bearlike-attackers.000webhostapp.com\/2017\/02\/16\/testy\/",
"title": {
"rendered": "Testy"
},
// And many other properties.
}]
注意到外面的 [
和 ]
了吗?您的问题是您的外部 JSON 容器是一个数组,而不是 object。如 JSON standard 中所述:
数组是有序的 collection 值。数组以
[
(左括号)开始,以]
(右括号)结束。值由,
(逗号)分隔。object 是 name/value 对的无序集合。 object 以
{
(左大括号)开始,以}
(右大括号)结束。
DataContractJsonSerializer
将 JSON 数组序列化为 .Net collection 类型,例如 List<T>
和 T []
。因此,您必须按如下方式反序列化:
public async static Task<List<RootObject>> Get()
{
var http = new HttpClient();
var response = await http.GetAsync("http://bearlike-attackers.000webhostapp.com/wp-json/wp/v2/posts?search=TEST");
var result = await response.Content.ReadAsStringAsync();
var serializer = new DataContractJsonSerializer(typeof(List<RootObject>));
var ms = new MemoryStream(Encoding.UTF8.GetBytes(result));
var list = (List<RootObject>)serializer.ReadObject(ms);
return list;
}
如果您确定您的服务只会 return 一项,您可以使用 Enumerable.SingleOrDefault()
:
RootObject
return list.SingleOrDefault();
让我有点惊讶的是DataContractJsonSerializer
在这种情况下默默地什么都不做。 json.net throws an Unexpected token: StartArray
这种情况例外。
最后,用于标题的 属性 名称是 "rendered"
而不是 "title"
。因此你的 Title
class 需要看起来像:
[DataContract]
public class Title
{
[DataMember]
public string rendered { get; set; }
}
要访问它的值,请执行(根据需要添加任何空检查):
var s = myPost.id + " - " + myPost.author + "-" + myPost.title.rendered;
(我还没有检查你的其他数据合同成员名称的正确性。你应该检查,因为有一个不正确。)