c# - 强大的表单 API JSON 响应 C# 对象
问题描述
我有一些从Formidable Forms API返回的 Json,但我正在努力将其转换为 (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 );
编辑:
在这篇文章的帮助下,我能够更接近一点。我可以获得一个密钥列表,但前提是我知道源名称(在这种情况下为 mrjgb),但名称是随机的,所以我不提前知道......
JToken outer = JToken.Parse( response.Content );
JObject inner = outer[ "mrjgb" ].Value<JObject>();
List<string> keys = inner.Properties().Select( p => p.Name ).ToList();
解决方案
The API response is a JSON object, which translates to a .NET Dictionary<string, ?>
. Instead of deserializing to a List
or dynamic
, use 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);
I used QuickType to quickly generate the classes that represent the API response structure:
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; }
}
Try it: fiddle
推荐阅读
- unit-testing - 在 Golang 中对 GraphQL 进行单元测试
- javascript - 如何在 vscode 中禁用自动删除行空间?
- python - 如何删除某个字符后的所有内容?
- javascript - 使用 useEffect 钩子在反应功能组件中未使用 .map() 显示的元素
- sql - SQL Server:如何返回最高聚合列
- flask - 在 Flask WTForms 中使用 RadioField 公开其他表单字段
- javascript - 如何过滤排行榜排名
- ubuntu - 如何修复 Fontconfig 警告 - 未知元素错误
- android - 使用视图绑定时布局不居中
- mysql - 将项目启动到云/生产(Node.js + Vue.js)