从c#

时间:2018-10-15 07:23:09

标签: c# arrays json datatable

我有一个如下所示的数据表,其中包含几列。 datatable列之一具有作为json数组(Contacts)的值。我想从列访问name属性。

Name     ID    Contacts 
User1    1     [{ "id": 1, "name": "User3", } }]]

1 个答案:

答案 0 :(得分:1)

此表包含JSON字符串,而不是数组。要获取该字段的内容,必须使用JSON.NET将其反序列化并读取其内容,例如:

var contactValue=(string)table.Rows[0]["Contacts"];            
var contacts=JsonConvert.DeserializeObject<dynamic>(contactValue);
Console.WriteLine("{0}",contacts[0].name);

JsonConvert.DeserializeObject可以将JSON字符串反序列化为具体类型或动态对象。在此示例中,内容反序列化为包含数组的动态对象。 contacts[0].name将返回第一个元素的名称属性。

在这种情况下,最好创建一个具体的类型而不是使用动态类型:

class Contact 
{
        public int id {get;set;}
        public string name{get;set;}
}

这允许使用LINQ检索特定属性,例如:

var  contacts=JsonConvert.DeserializeObject<Contact[]>(contactValue);

//Iterate over the results
foreach(var contact in contacts)
{
    Console.WriteLine(contact.name);
}
//Or use LINQ
var names=contacts.Select(it=>it.name).ToList();

使用JSONPath

另一种选择是使用JSONPath提取特定值而不解析整个字符串。

不是对字符串进行反序列化,而是使用JArray.ParseJObject.Parse对其进行解析。之后,SelectTokens用于检索与查询路径匹配的值:

var array=JArray.Parse(contactValue);
var tokens=array.SelectTokens("$..name");
foreach(var token in tokens)
{
    Console.WriteLine(token);
}
//Concatenate all names into a string
string allNames=String.Join(",",tokens);

$..name表示

  

对于任何元素,无论其在层次结构(name中的位置如何,都应返回名为..的任何属性