强大的表单 API JSON 对 C# 对象的响应
Formidable Forms API JSON Response to C# Object
我有一些 Json 从 Formidable Forms API 返回,但我正在努力将其转换为 (c#) 对象列表。返回的 json 不是一个对象数组,所以当我尝试反序列化为一个对象时(使用 newtonsoft.json),我得到一个错误:
Cannot deserialize the current JSON object (e.g. {"name":"value"}) into type 'System.Collections.Generic.List...because the type requires a JSON array (e.g. [1,2,3]) to deserialize correctly.
这是返回的 Json 的片段。
{
"mrjgb": {
"id": "50",
"item_key": "mrjgb",
"name": "John",
"ip": "",
"meta": {
"first_name": "John",
"middle_initial": "T",
"last_name": "Doe",
"date": "August 15, 2019",
"date-value": "2019-08-15"
},
"form_id": "15",
"post_id": "0",
"user_id": "0",
"parent_item_id": "0",
"is_draft": "0",
"updated_by": "0",
"created_at": "2019-08-15 18:10:59",
"updated_at": "2019-08-15 18:10:59"
},
"9rs0q": {
"id": "48",
"item_key": "9rs0q",
"name": "dsdds",
"ip": "",
"meta": {
"first_name": "dsdds",
"middle_initial": "",
"last_name": "23112qead",
"date": "August 13, 2019",
"date-value": "2019-08-13"
},
"form_id": "15",
"post_id": "0",
"user_id": "25",
"parent_item_id": "0",
"is_draft": "0",
"updated_by": "25",
"created_at": "2019-08-13 13:43:23",
"updated_at": "2019-08-13 13:43:23"
}
}
在此片段中有两个对象,mrjgb 和 9rs0q,但可以有任意数量的这些对象,并且它们没有设置名称。
有人能给我指出正确的方向吗?我做了很多尝试,都取得了不同程度的成功。
//List<Foo> foo = JsonConvert.DeserializeObject<List<Foo>>( response.Content );
//var Foo = JsonConvert.DeserializeObject<List<Foo>>( response.Content, new FooConverter() );
//var results = JsonConvert.DeserializeObject<List<dynamic>>( response.Content );
var FooList = new List<Foo>();
var results = JsonConvert.DeserializeObject<dynamic>( response.Content );
//var results33 = JsonConvert.DeserializeObject<Foo>( results );
//var Foos = JsonConvert.DeserializeObject<List<Foo>>( results, new FooConverter() );
foreach (var token in results )
{
var Foo = JsonConvert.DeserializeObject<Foo>( token, new FooConverter() );
//var Foo = JsonConvert.DeserializeObject<Foo>( results, new FooConverter() ); // passes all tokens, not just the one we want to convert
FooList.Add( Foo );
}
//var Foo = JsonConvert.DeserializeObject<Foo>( response.Content );
编辑:
在 this post 的帮助下,我离得更近了一点。我可以获得密钥列表,但前提是我知道源名称(在本例中为 mrjgb),但该名称是随机的,所以我无法提前知道它....
JToken outer = JToken.Parse( response.Content );
JObject inner = outer[ "mrjgb" ].Value<JObject>();
List<string> keys = inner.Properties().Select( p => p.Name ).ToList();
API 响应是一个 JSON 对象,转换为 .NET Dictionary<string, ?>
。不要反序列化为 List
或 dynamic
,而是使用 Dictionary<string, FormidableFormsResponse>
:
var response = JsonConvert.DeserializeObject<Dictionary<string, FormidableFormsResponse>>(json);
Console.WriteLine($"{response.Keys.Count} items in the response");
var firstItem = response.ElementAt(0).Value;
Console.WriteLine(firstItem.Name);
var secondItem = response.ElementAt(1).Value;
Console.WriteLine(secondItem.Name);
我使用 QuickType 快速生成了代表 API 响应结构的 类:
public class FormidableFormsResponse
{
[JsonProperty("id")]
public long Id { get; set; }
[JsonProperty("item_key")]
public string ItemKey { get; set; }
[JsonProperty("name")]
public string Name { get; set; }
[JsonProperty("ip")]
public string Ip { get; set; }
[JsonProperty("meta")]
public Meta Meta { get; set; }
[JsonProperty("form_id")]
public long FormId { get; set; }
[JsonProperty("post_id")]
public long PostId { get; set; }
[JsonProperty("user_id")]
public long UserId { get; set; }
[JsonProperty("parent_item_id")]
public long ParentItemId { get; set; }
[JsonProperty("is_draft")]
public long IsDraft { get; set; }
[JsonProperty("updated_by")]
public long UpdatedBy { get; set; }
[JsonProperty("created_at")]
public DateTimeOffset CreatedAt { get; set; }
[JsonProperty("updated_at")]
public DateTimeOffset UpdatedAt { get; set; }
}
public class Meta
{
[JsonProperty("first_name")]
public string FirstName { get; set; }
[JsonProperty("middle_initial")]
public string MiddleInitial { get; set; }
[JsonProperty("last_name")]
public string LastName { get; set; }
[JsonProperty("date")]
public string Date { get; set; }
[JsonProperty("date-value")]
public DateTimeOffset DateValue { get; set; }
}
试一试:fiddle
您可以通过 JsonConverter.DeserializeObject
方法解析它,returns 您是一个对象 (JObject)。然后你可以使用这个对象,其中 mrjgb 将是 JProperty 而 9rs0q 将是另一个 JProperty 来自同一对象 (JObject)
var result = (JObject) JsonConvert.DeserializeObject(response.Content);
foreach (var r in result.Children())
{
// Do what you need to do here, r.First is the mrjgb/9rs0q/whatever object
var _foo = r.First.ToObject<Foo>();
FooList.Add( Foo );
}
我有一些 Json 从 Formidable Forms API 返回,但我正在努力将其转换为 (c#) 对象列表。返回的 json 不是一个对象数组,所以当我尝试反序列化为一个对象时(使用 newtonsoft.json),我得到一个错误:
Cannot deserialize the current JSON object (e.g. {"name":"value"}) into type 'System.Collections.Generic.List...because the type requires a JSON array (e.g. [1,2,3]) to deserialize correctly.
这是返回的 Json 的片段。
{
"mrjgb": {
"id": "50",
"item_key": "mrjgb",
"name": "John",
"ip": "",
"meta": {
"first_name": "John",
"middle_initial": "T",
"last_name": "Doe",
"date": "August 15, 2019",
"date-value": "2019-08-15"
},
"form_id": "15",
"post_id": "0",
"user_id": "0",
"parent_item_id": "0",
"is_draft": "0",
"updated_by": "0",
"created_at": "2019-08-15 18:10:59",
"updated_at": "2019-08-15 18:10:59"
},
"9rs0q": {
"id": "48",
"item_key": "9rs0q",
"name": "dsdds",
"ip": "",
"meta": {
"first_name": "dsdds",
"middle_initial": "",
"last_name": "23112qead",
"date": "August 13, 2019",
"date-value": "2019-08-13"
},
"form_id": "15",
"post_id": "0",
"user_id": "25",
"parent_item_id": "0",
"is_draft": "0",
"updated_by": "25",
"created_at": "2019-08-13 13:43:23",
"updated_at": "2019-08-13 13:43:23"
}
}
在此片段中有两个对象,mrjgb 和 9rs0q,但可以有任意数量的这些对象,并且它们没有设置名称。
有人能给我指出正确的方向吗?我做了很多尝试,都取得了不同程度的成功。
//List<Foo> foo = JsonConvert.DeserializeObject<List<Foo>>( response.Content );
//var Foo = JsonConvert.DeserializeObject<List<Foo>>( response.Content, new FooConverter() );
//var results = JsonConvert.DeserializeObject<List<dynamic>>( response.Content );
var FooList = new List<Foo>();
var results = JsonConvert.DeserializeObject<dynamic>( response.Content );
//var results33 = JsonConvert.DeserializeObject<Foo>( results );
//var Foos = JsonConvert.DeserializeObject<List<Foo>>( results, new FooConverter() );
foreach (var token in results )
{
var Foo = JsonConvert.DeserializeObject<Foo>( token, new FooConverter() );
//var Foo = JsonConvert.DeserializeObject<Foo>( results, new FooConverter() ); // passes all tokens, not just the one we want to convert
FooList.Add( Foo );
}
//var Foo = JsonConvert.DeserializeObject<Foo>( response.Content );
编辑:
在 this post 的帮助下,我离得更近了一点。我可以获得密钥列表,但前提是我知道源名称(在本例中为 mrjgb),但该名称是随机的,所以我无法提前知道它....
JToken outer = JToken.Parse( response.Content );
JObject inner = outer[ "mrjgb" ].Value<JObject>();
List<string> keys = inner.Properties().Select( p => p.Name ).ToList();
API 响应是一个 JSON 对象,转换为 .NET Dictionary<string, ?>
。不要反序列化为 List
或 dynamic
,而是使用 Dictionary<string, FormidableFormsResponse>
:
var response = JsonConvert.DeserializeObject<Dictionary<string, FormidableFormsResponse>>(json);
Console.WriteLine($"{response.Keys.Count} items in the response");
var firstItem = response.ElementAt(0).Value;
Console.WriteLine(firstItem.Name);
var secondItem = response.ElementAt(1).Value;
Console.WriteLine(secondItem.Name);
我使用 QuickType 快速生成了代表 API 响应结构的 类:
public class FormidableFormsResponse
{
[JsonProperty("id")]
public long Id { get; set; }
[JsonProperty("item_key")]
public string ItemKey { get; set; }
[JsonProperty("name")]
public string Name { get; set; }
[JsonProperty("ip")]
public string Ip { get; set; }
[JsonProperty("meta")]
public Meta Meta { get; set; }
[JsonProperty("form_id")]
public long FormId { get; set; }
[JsonProperty("post_id")]
public long PostId { get; set; }
[JsonProperty("user_id")]
public long UserId { get; set; }
[JsonProperty("parent_item_id")]
public long ParentItemId { get; set; }
[JsonProperty("is_draft")]
public long IsDraft { get; set; }
[JsonProperty("updated_by")]
public long UpdatedBy { get; set; }
[JsonProperty("created_at")]
public DateTimeOffset CreatedAt { get; set; }
[JsonProperty("updated_at")]
public DateTimeOffset UpdatedAt { get; set; }
}
public class Meta
{
[JsonProperty("first_name")]
public string FirstName { get; set; }
[JsonProperty("middle_initial")]
public string MiddleInitial { get; set; }
[JsonProperty("last_name")]
public string LastName { get; set; }
[JsonProperty("date")]
public string Date { get; set; }
[JsonProperty("date-value")]
public DateTimeOffset DateValue { get; set; }
}
试一试:fiddle
您可以通过 JsonConverter.DeserializeObject
方法解析它,returns 您是一个对象 (JObject)。然后你可以使用这个对象,其中 mrjgb 将是 JProperty 而 9rs0q 将是另一个 JProperty 来自同一对象 (JObject)
var result = (JObject) JsonConvert.DeserializeObject(response.Content);
foreach (var r in result.Children())
{
// Do what you need to do here, r.First is the mrjgb/9rs0q/whatever object
var _foo = r.First.ToObject<Foo>();
FooList.Add( Foo );
}