我正在尝试读取一个json文件,该文件非常复杂,可以在foreach语句中动态访问JArray。但是我得到一个错误,说明'当前的JsonReader项不是一个数组'我能够访问键和值,如果我使用一个JObject,但这不是我需要的,我需要能够通过记录和按名称或ID等搜索。我在newtwonsoft和JSON.net有点新,所以任何帮助都将不胜感激!
JArray o1 = JArray.Parse(File.ReadAllText(@"myfilepath"));
dynamic records = o1;
foreach (dynamic record in records)
{
Console.WriteLine(record.Id + " (" + record.Name + ")");
}
我的json文件看起来像这样,有多条记录,但我缩短了它。我需要通过Id或Name访问和搜索,但我遇到了访问问题。
String json = @"{
"RecordSetBundles" : [ {
"Records" : [ {
"attributes" : {
"type" : "nihrm__Location__c",
"url" : "/services/data/v38.0/sobjects/nihrm__Location__c/a0di0000001nI3oAAE"
},
"CurrencyIsoCode" : "USD",
"Id" : "a0di0000001nI3oAAE",
"Name" : "The City Hotel",
"nihrm__Abbreviation__c" : "TCH",
"nihrm__AddressLine1__c" : "1 Main Street",
"nihrm__AlternateNameES__c" : "El Ciudad Hotel",
"nihrm__AvailabilityScreenView__c" : "Combined",
"nihrm__Geolocation__c" : null,
"nihrm__HideBookingsFromPortal__c" : false,
"nihrm__IsActive__c" : true,
"nihrm__IsPlannerPortalEnabled__c" : false,
"nihrm__isRemoveCancelledEventsFromBEOs__c" : false,
"nihrm__ManagementAffliation__c" : "NI International",
"nihrm__NearestAirportCode__c" : "MHT",
"nihrm__Phone__c" : "(207) 555-5555",
"nihrm__PostalCode__c" : "04103",
"nihrm__PropertyCode__c" : "TCH",
"nihrm__RegionName__c" : "Northeast",
"nihrm__RestrictBookingMoveWithPickup__c" : true,
"nihrm__RohAllowedStatuses__c" : "Prospect;Tentative;Definite",
"nihrm__StateProvince__c" : "ME",
"nihrm__SystemOfMeasurement__c" : "Standard",
"nihrm__TimeZone__c" : "GMT-05:00 Eastern Daylight Time (America/New_York)",
"nihrm__UpdateBookingEventAverageChecks__c" : false,
"nihrm__UseAlternateLanguage__c" : false,
"nihrm__Website__c" : "www.thecityhotelweb.com"
} ],
"ObjectType" : "nihrm__Location__c",
"DeleteFirst" : false
},
以下是整个json的链接: https://codeshare.io/rGL6K5
答案 0 :(得分:1)
您是否知道每次发出请求时您的JSon对象的属性是否相同?不是价值,只是名字?如果是这样,请创建一个具体类型并使用JSonObjectSerializer反序列化为一个对象。如果应该能够在该对象上创建一个字典集合,将您的JSon数据反序列化为键值对。然后,您可以通过Keys集合像任何其他集合一样进行迭代。
除非你真的不知道你在输入上处理什么,否则你真的不需要使用动态对象。确定每次发出请求时您的传入数据是否具有一致的属性名称。
一个例子可能是
var myData = JsonSerializer.Deserialize<myDataType>(incomingTextData);
myDataType将有一个可以处理你的数组的集合。
答案 1 :(得分:1)
此错误Current JsonReader item is not an Array
是不言自明的:解析的对象不是数组。但是如果没有看到Json我们只能假设这个Json是object
并且如果你想使用动态对象更改代码如下:
dynamic myJson = JsonConvert.DeserializeObject(File.ReadAllText(@"myfilepath"));
var currency = myJson.RecordSetBundles[0].Records[0].CurrencyIsoCode
//Access to other property in your dynamic object
编辑
您的JSON对象看起来相当复杂,通过动态访问可能很复杂我建议您使用JsonConvert.DeserializeObject<T>(string)
从你发布的json开始,这个类看起来像这样:
public class Attributes
{
public string type { get; set; }
public string url { get; set; }
}
public class Record
{
public Attributes attributes { get; set; }
public string CurrencyIsoCode { get; set; }
public string Id { get; set; }
public string Name { get; set; }
public string nihrm__Abbreviation__c { get; set; }
public string nihrm__AddressLine1__c { get; set; }
public string nihrm__AlternateNameES__c { get; set; }
public string nihrm__AvailabilityScreenView__c { get; set; }
public object nihrm__Geolocation__c { get; set; }
public bool nihrm__HideBookingsFromPortal__c { get; set; }
public bool nihrm__IsActive__c { get; set; }
public bool nihrm__IsPlannerPortalEnabled__c { get; set; }
public bool nihrm__isRemoveCancelledEventsFromBEOs__c { get; set; }
public string nihrm__ManagementAffliation__c { get; set; }
public string nihrm__NearestAirportCode__c { get; set; }
public string nihrm__Phone__c { get; set; }
public string nihrm__PostalCode__c { get; set; }
public string nihrm__PropertyCode__c { get; set; }
public string nihrm__RegionName__c { get; set; }
public bool nihrm__RestrictBookingMoveWithPickup__c { get; set; }
public string nihrm__RohAllowedStatuses__c { get; set; }
public string nihrm__StateProvince__c { get; set; }
public string nihrm__SystemOfMeasurement__c { get; set; }
public string nihrm__TimeZone__c { get; set; }
public bool nihrm__UpdateBookingEventAverageChecks__c { get; set; }
public bool nihrm__UseAlternateLanguage__c { get; set; }
public string nihrm__Website__c { get; set; }
}
public class RecordSetBundle
{
public List<Record> Records { get; set; }
public string ObjectType { get; set; }
public bool DeleteFirst { get; set; }
}
public class RootObject
{
public List<RecordSetBundle> RecordSetBundles { get; set; }
}
使用Newtonsoft
:
var myObject = JsonConvert.DeserializeObject<RootObject>(myJsonStrin);
答案 2 :(得分:1)
其他答案显示强类型课程。如果你能做到这一点,你确定结构不会改变,我建议你这样做。这将使其他一切变得更加容易。
如果你想用动态对象来做,那么你可以通过这种方式得到你想要的东西。
// GET JSON DATA INTO DYNAMIC OBJECT
var data = JsonConvert.DeserializeObject<dynamic>(File.ReadAllText(@"myfilepath"));
// GET TOP LEVEL "RecordSetBundles" OBJECT
var bundles = data.RecordSetBundles;
// LOOP THROUGH EACH BUNDLE OF RECORDS
foreach (var bundle in bundles)
{
// GET THE RECORDS IN THIS BUNDLE
var records = bundle.Records;
// LOOP THROUGH THE RECORDS
foreach (var record in records)
{
// WRITE TO CONSOLE
Console.WriteLine(record.Id.ToString() + " (" + record.Name.ToString() + ")");
}
}
生成此输出:
a0di0000001nI3oAAE(城市酒店)
a0xi0000000jOQCAA2(8轮)
a0xi0000001aUbfAAE(附加服务)
a0xi0000004ZnehAAC(全市)
a0xi0000001YXcCAAW(Cocktail Rounds)
等等