如何使用Newtonsoft在复杂的json文件c#/中获取密钥

如何使用Newtonsoft在复杂的json文件c#/中获取密钥,c#,json,json.net,C#,Json,Json.net,如何使用Newtonsoft获取复杂json文件的密钥 我不明白如何在json中获取密钥,因为json在代码中很难实现: 我使用以下方法读取我的json: 从json读取是可以的,但我仍然无法获取所有的键/属性 _id/产品名称/供应商/数量/单位成本 { "product": [ { "_id": { "$oid": "5968dd23fc13ae04d9000001" },

如何使用Newtonsoft获取复杂json文件的密钥

我不明白如何在json中获取密钥,因为json在代码中很难实现:

我使用以下方法读取我的json:

从json读取是可以的,但我仍然无法获取所有的键/属性 _id/产品名称/供应商/数量/单位成本

{
    "product": [
        {
            "_id": {
                "$oid": "5968dd23fc13ae04d9000001"
            },
            "product_name": "sildenafil citrate",
            "supplier": "Wisozk Inc",
            "quantity": 261,
            "unit_cost": "$10.47"
        },
        {
            "_id": {
                "$oid": "5968dd23fc13ae04d9000002"
            },
            "product_name": "Mountain Juniperus ashei",
            "supplier": "Keebler-Hilpert",
            "quantity": 292,
            "unit_cost": "$8.74"
        },
        {
            "_id": {
                "$oid": "5968dd23fc13ae04d9000003"
            },
            "product_name": "Dextromathorphan HBr",
            "supplier": "Schmitt-Weissnat",
            "quantity": 211,
            "unit_cost": "$20.53"
        }
    ]
}
但我只想得到字段名: _身份证 产品名称 供应商 量 单位成本

我希望这样:但在我的代码中似乎不起作用:


谢谢,

更新:

OP提供的密钥列表可以按如下方式获取:

            "_id": {
                "$oid": "5968dd23fc13ae04d9000001"
            },
            "product_name": "sildenafil citrate",
            "supplier": "Wisozk Inc",
            "quantity": 261,
            "unit_cost": "$10.47"
        },
GetFieldNames()

公共静态列表GetFieldName(动态输入)
{
列表字段名=新列表();
尝试
{
//将输入json字符串反序列化为对象
input=Newtonsoft.Json.JsonConvert.DeserializeObject(输入);
//Json对象可以包含数组或对象,也可以仅包含值
//对于字段名,导航到根或第一个元素
输入=输入。根??输入。第一??输入;
如果(输入!=null)
{
//获取数组中的第一个元素
bool-isArray=true;
while(isArray)
{
输入=输入。第一个??输入;
if(input.GetType()==typeof(Newtonsoft.Json.Linq.JObject)|
input.GetType()==typeof(Newtonsoft.Json.Linq.JValue)|
输入==null)
isArray=假;
}
//检查对象是否为JObject类型。
//如果是,请阅读该作业对象的属性
if(input.GetType()==typeof(Newtonsoft.Json.Linq.JObject))
{
//从对象创建作业对象
Newtonsoft.Json.Linq.JObject inputJson=
Newtonsoft.Json.Linq.JObject.FromObject(输入);
//读取属性
var properties=inputJson.properties();
//循环遍历该JObject的所有属性
foreach(属性中的var属性)
{
//检查是否有任何子字段(嵌套)
//也就是说,任何字段的值都是另一个JObject或另一个JArray
if(property.Value.GetType()==typeof(Newtonsoft.Json.Linq.JObject)|
property.Value.GetType()==typeof(Newtonsoft.Json.Linq.JArray))
{
//如果是,则输入递归循环以提取子字段名称
var subFields=GetFieldNames(property.Value.ToString());
if(subFields!=null&&subFields.Count()>0)
{
//将子字段名与字段名联接
//(如Field1.SubField1、Field1.SubField2等)
fieldNames.AddRange(
子域
.选择(n=>
string.IsNullOrEmpty(n)?属性。名称:
string.Format(“{0}.{1}”,property.Name,n));
}
}
其他的
{
//如果没有子字段,则属性名称为字段名称
fieldNames.Add(property.Name);
}
}
}
其他的
if(input.GetType()==typeof(Newtonsoft.Json.Linq.JValue))
{
//对于直接值,没有字段名
fieldNames.Add(string.Empty);
}
}
}
抓住
{
投掷;
}
返回字段名;
}

我怀疑您希望将JSON加载到JObject中,而不是将其反序列化到您自己的自定义类中。(使用
JObject.Parse
而不是
JsonConvert.DeserializeObject
)是的,我只是不明白如何使用这个:JObject o=JObject.Parse(json);因为现在每次点击一个按钮,我都会在一个对象中加载完整的json并运行它。我认为不好的地方。@yave你想要一本字典吗?@yave看到我的最新答案,如果需要,请告诉我helps@yave这对我来说很好。我试过你的JSON@yave我还展示了这个方法,并在我的回答中附上了一个屏幕截图。@yave你能调试并查看哪行代码崩溃吗?
            "_id": {
                "$oid": "5968dd23fc13ae04d9000001"
            },
            "product_name": "sildenafil citrate",
            "supplier": "Wisozk Inc",
            "quantity": 261,
            "unit_cost": "$10.47"
        },
using (StreamReader r = new StreamReader("Json_1.json"))
{
    string json = r.ReadToEnd();        
    var obj = JObject.Parse(json);
    foreach (var o in obj)
    {
        var result = GetFieldNames(o.Value.ToString());
    }
}
public static List<string> GetFieldNames(dynamic input)
{
    List<string> fieldNames = new List<string>();

    try
    {
        // Deserialize the input json string to an object
        input = Newtonsoft.Json.JsonConvert.DeserializeObject(input);

        // Json Object could either contain an array or an object or just values
        // For the field names, navigate to the root or the first element
        input = input.Root ?? input.First ?? input;

        if (input != null)
        {
            // Get to the first element in the array
            bool isArray = true;
            while (isArray)
            {
                input = input.First ?? input;

                if (input.GetType() == typeof(Newtonsoft.Json.Linq.JObject) || 
                input.GetType() == typeof(Newtonsoft.Json.Linq.JValue) || 
                input == null)
                    isArray = false;
            }

            // check if the object is of type JObject. 
            // If yes, read the properties of that JObject
            if (input.GetType() == typeof(Newtonsoft.Json.Linq.JObject))
            {
                // Create JObject from object
                Newtonsoft.Json.Linq.JObject inputJson = 
                    Newtonsoft.Json.Linq.JObject.FromObject(input);

                // Read Properties
                var properties = inputJson.Properties();

                // Loop through all the properties of that JObject
                foreach (var property in properties)
                {
                    // Check if there are any sub-fields (nested)
                    // i.e. the value of any field is another JObject or another JArray
                    if (property.Value.GetType() == typeof(Newtonsoft.Json.Linq.JObject) || 
                    property.Value.GetType() == typeof(Newtonsoft.Json.Linq.JArray))
                    {
                        // If yes, enter the recursive loop to extract sub-field names
                        var subFields = GetFieldNames(property.Value.ToString());

                        if (subFields != null && subFields.Count() > 0)
                        {
                            // join sub-field names with field name 
                            //(e.g. Field1.SubField1, Field1.SubField2, etc.)
                            fieldNames.AddRange(
                                subFields
                                .Select(n =>
                                string.IsNullOrEmpty(n) ? property.Name :
                             string.Format("{0}.{1}", property.Name, n)));
                        }
                    }
                    else
                    {
                        // If there are no sub-fields, the property name is the field name
                        fieldNames.Add(property.Name);
                    }
                }
            }
            else
                if (input.GetType() == typeof(Newtonsoft.Json.Linq.JValue))
            {
                // for direct values, there is no field name
                fieldNames.Add(string.Empty);
            }
        }
    }
    catch
    {
        throw;
    }

    return fieldNames;
}