使用 C# 访问深度嵌套 json 中的特定 属性 并将其添加到数组
Access a specific property in deeply nested json using c# and add it to an array
我试图访问下面 json 中 OperationId 的所有值并将其添加到一个数组中,但在我向下钻取数据时它一直给我一个 null 异常。以下是 json,如有任何关于如何直接访问 operationIds 的建议,我们将不胜感激。
注意:所有控制器名称和 HttpVerbs 在整个 json 中都是可变的,这只是 10,000 行 Json 文件中的一小部分,因此对每个值进行硬编码获取字符串无效。
Json:
{
"swagger": "2.0",
"info": {
"version": "v1",
"title": "API Services"
},
"host": "TestApi.Com",
"basePath": "/TestApi",
"schemes": ["https"],
"paths": {
"/activity/actions": {
"get": {
"tags": ["activities"],
"summary": "Returns a list of non-hidden Actions.",
"description": "Test Description",
***"operationId": "GET/activity/actions", //Need to add this to array***
"consumes": [],
"produces": ["application/json", "text/json", "application/xml", "text/xml"],
"responses": {
"200": {
"description": "OK",
"schema": {
"type": "array",
"items": {
"$ref": "#/definitions/ActionResponse"
}
}
}
}
},
"put": {
"tags": ["activities"],
"summary": "Updates any/all existing ActivityActions by matching Id",
"description": "Test Description",
***"operationId": "PUT/activity/actions", //Need to add this to array***
"consumes": ["application/json", "text/json", "application/xml", "text/xml", "application/x-www-form-urlencoded"],
"produces": ["application/json", "text/json", "application/xml", "text/xml"],
"parameters": [{
"name": "List`1",
"in": "body",
"required": true,
"schema": {
"type": "array",
"items": {
"$ref": "#/definitions/ActivityActionPutRequest"
}
}
}, {
"name": "Authorization",
"in": "header",
"description": "AccessToken",
"required": false,
"type": "string"
}],
"responses": {
"200": {
"description": "OK",
"schema": {
"type": "array",
"items": {
"$ref": "#/definitions/ActivityActionUpdateResponse"
}
}
}
}
}
},
"/activity/agency-url/create": {
"get": {
"tags": ["activities"],
"summary": "Test",
***"operationId": "GET/activity/agency-url/create", //Need to add this to array***
"consumes": [],
"produces": ["application/json", "text/json", "application/xml", "text/xml"],
"parameters": [{
"name": "EntityType",
"in": "query",
"description": "Test",
"required": true,
"type": "string"
}, {
"name": "EntityId",
"in": "query",
"description": "The Guid or Sequence No of the entity.",
"required": true,
"type": "string"
}, {
"name": "Authorization",
"in": "header",
"description": "AccessToken",
"required": false,
"type": "string"
}],
"responses": {
"200": {
"description": "OK",
"schema": {
"$ref": "#/definitions/ActivityUrlResponse"
}
}
}
}
}
}
}
因此输出将如下所示:
[GET/activity/actions, PUT/activity/actions, GET/activity/agency-url/create]
首先定义 JSON 结构 - 这只是读取所需字段所需的最小结构:
public class RootJson
{
public Paths paths { get; set; }
}
public class Paths : Dictionary<string, ActivityActions> { }
public class ActivityActions
{
public Get get { get; set; }
public Put put { get; set; }
}
public class Get
{
public string operationId { get; set; }
}
public class Put
{
public string operationId { get; set; }
}
然后像这样提取数据(我读的是所有 gets 然后是 all puts,您可能需要不同的顺序):
var json = "{ ... define your json }";
var test = JsonConvert.DeserializeObject<RootJson>(json);
var result = new List<string>();
result.AddRange(test.paths.Select(p => p.Value.get?.operationId).Where(oid => oid != null));
result.AddRange(test.paths.Select(p => p.Value.put?.operationId).Where(oid => oid != null));
现在 result 包含您想要的列表。
所以我会使用Newtonsoft的方法。
像这样:
private static IEnumerable<JToken> GetToFindPropertiesAsJTokens(string json)
{
IEnumerable<JToken> jTokens = null;
JObject jObject = JObject.Parse(json);
jTokens = jObject.Descendants()
.Where(t => t.Type == JTokenType.Property && ((JProperty)t).Name == "operationId")
.Select(p => ((JProperty)p).Value);
return jTokens;
}
使用:
List<string> values = new List<string>();
foreach (JToken jtoken in GetToFindPropertiesAsJTokensBasedOnTable(json))
{
values.Add(jtoken.ToString());
}
string[] valuesArray = values.ToArray();
Array.ForEach(valuesArray, x=> Console.WriteLine(x));
输出:
GET/activity/actions
PUT/activity/actions
GET/activity/agency-url/create
我试图访问下面 json 中 OperationId 的所有值并将其添加到一个数组中,但在我向下钻取数据时它一直给我一个 null 异常。以下是 json,如有任何关于如何直接访问 operationIds 的建议,我们将不胜感激。
注意:所有控制器名称和 HttpVerbs 在整个 json 中都是可变的,这只是 10,000 行 Json 文件中的一小部分,因此对每个值进行硬编码获取字符串无效。
Json:
{
"swagger": "2.0",
"info": {
"version": "v1",
"title": "API Services"
},
"host": "TestApi.Com",
"basePath": "/TestApi",
"schemes": ["https"],
"paths": {
"/activity/actions": {
"get": {
"tags": ["activities"],
"summary": "Returns a list of non-hidden Actions.",
"description": "Test Description",
***"operationId": "GET/activity/actions", //Need to add this to array***
"consumes": [],
"produces": ["application/json", "text/json", "application/xml", "text/xml"],
"responses": {
"200": {
"description": "OK",
"schema": {
"type": "array",
"items": {
"$ref": "#/definitions/ActionResponse"
}
}
}
}
},
"put": {
"tags": ["activities"],
"summary": "Updates any/all existing ActivityActions by matching Id",
"description": "Test Description",
***"operationId": "PUT/activity/actions", //Need to add this to array***
"consumes": ["application/json", "text/json", "application/xml", "text/xml", "application/x-www-form-urlencoded"],
"produces": ["application/json", "text/json", "application/xml", "text/xml"],
"parameters": [{
"name": "List`1",
"in": "body",
"required": true,
"schema": {
"type": "array",
"items": {
"$ref": "#/definitions/ActivityActionPutRequest"
}
}
}, {
"name": "Authorization",
"in": "header",
"description": "AccessToken",
"required": false,
"type": "string"
}],
"responses": {
"200": {
"description": "OK",
"schema": {
"type": "array",
"items": {
"$ref": "#/definitions/ActivityActionUpdateResponse"
}
}
}
}
}
},
"/activity/agency-url/create": {
"get": {
"tags": ["activities"],
"summary": "Test",
***"operationId": "GET/activity/agency-url/create", //Need to add this to array***
"consumes": [],
"produces": ["application/json", "text/json", "application/xml", "text/xml"],
"parameters": [{
"name": "EntityType",
"in": "query",
"description": "Test",
"required": true,
"type": "string"
}, {
"name": "EntityId",
"in": "query",
"description": "The Guid or Sequence No of the entity.",
"required": true,
"type": "string"
}, {
"name": "Authorization",
"in": "header",
"description": "AccessToken",
"required": false,
"type": "string"
}],
"responses": {
"200": {
"description": "OK",
"schema": {
"$ref": "#/definitions/ActivityUrlResponse"
}
}
}
}
}
}
}
因此输出将如下所示:
[GET/activity/actions, PUT/activity/actions, GET/activity/agency-url/create]
首先定义 JSON 结构 - 这只是读取所需字段所需的最小结构:
public class RootJson
{
public Paths paths { get; set; }
}
public class Paths : Dictionary<string, ActivityActions> { }
public class ActivityActions
{
public Get get { get; set; }
public Put put { get; set; }
}
public class Get
{
public string operationId { get; set; }
}
public class Put
{
public string operationId { get; set; }
}
然后像这样提取数据(我读的是所有 gets 然后是 all puts,您可能需要不同的顺序):
var json = "{ ... define your json }";
var test = JsonConvert.DeserializeObject<RootJson>(json);
var result = new List<string>();
result.AddRange(test.paths.Select(p => p.Value.get?.operationId).Where(oid => oid != null));
result.AddRange(test.paths.Select(p => p.Value.put?.operationId).Where(oid => oid != null));
现在 result 包含您想要的列表。
所以我会使用Newtonsoft的方法。
像这样:
private static IEnumerable<JToken> GetToFindPropertiesAsJTokens(string json)
{
IEnumerable<JToken> jTokens = null;
JObject jObject = JObject.Parse(json);
jTokens = jObject.Descendants()
.Where(t => t.Type == JTokenType.Property && ((JProperty)t).Name == "operationId")
.Select(p => ((JProperty)p).Value);
return jTokens;
}
使用:
List<string> values = new List<string>();
foreach (JToken jtoken in GetToFindPropertiesAsJTokensBasedOnTable(json))
{
values.Add(jtoken.ToString());
}
string[] valuesArray = values.ToArray();
Array.ForEach(valuesArray, x=> Console.WriteLine(x));
输出:
GET/activity/actions
PUT/activity/actions
GET/activity/agency-url/create