英文:
JsonConvert.DeserializeObject - Current JsonReader item is not an object: StartArray
问题
以下是代码的部分翻译:
// 在 DeserializeObject 时出现错误,错误信息是在 JObject.Load(reader) 处抛出的。
// 'Error reading JObject from JsonReader. Current JsonReader item is not an object: StartArray. Path '', line 1, position 1.'
// 这是 JSON 响应:
var responseData = "[{"Channels":[{"Channel":55,"DataRate":60,"Offset":0,"PreScaled":{"Flags":null,"Reading":4.809,"ValidPercentage":100},"RedactedPercentage":0,"Scaled":{"Flags":null,"Reading":4.809,"ValidPercentage":100},"SensorLabel":"FLOW","SensorName":"Flow","Slope":1,"UniqueId":685100,"UnitName":"Litres Per Minute"},{"Channel":57,"DataRate":60,"Offset":0,"PreScaled":{"Flags":null,"Reading":60.43,"ValidPercentage":100},"RedactedPercentage":0,"Scaled":{"Flags":null,"Reading":60.43,"ValidPercentage":100},"SensorLabel":"HUM","SensorName":"Humidity","Slope":1,"UniqueId":685100,"UnitName":"Percent"}],"Location":{"Altitude":null,"Latitude":52.20175,"Longitude":-1.7266},"Timestamp":{"Convention":"TimeBeginning","Timestamp":"2023-05-29T10:23:00+00:00"}},{"Channels":[{"Channel":55,"DataRate":60,"Offset":0,"PreScaled":{"Flags":null,"Reading":4.803,"ValidPercentage":100},"RedactedPercentage":0,"Scaled":{"Flags":null,"Reading":4.803,"ValidPercentage":100},"SensorLabel":"FLOW","SensorName":"Flow","Slope":1,"UniqueId":685100,"UnitName":"Litres Per Minute"}],"Location":{"Altitude":null,"Latitude":52.20175,"Longitude":-1.7266},"Timestamp":{"Convention":"TimeBeginning","Timestamp":"2023-05-29T10:22:00+00:00"}}]";
// 使用以下代码进行反序列化:
ReferenceStationData jsonLatestData = JsonConvert.DeserializeObject<ReferenceStationData>(responseData, new JsonSerializerSettings{DateTimeZoneHandling = DateTimeZoneHandling.Utc});
// 下面是代码示例链接:
// https://dotnetfiddle.net/wEUZ83
希望这有助于你理解代码的部分翻译。如果有任何其他问题,请随时提出。
英文:
I am trying to map the JSON nodes to my class using path and get an error when DeserializeObject. Error is thrown at JObject.Load(reader).
'Error reading JObject from JsonReader. Current JsonReader item is not an object: StartArray. Path '', line 1, position 1.'
Here is Json response;
var responseData = "[{\"Channels\":[{\"Channel\":55,\"DataRate\":60,\"Offset\":0,\"PreScaled\":{\"Flags\":null,\"Reading\":4.809,\"ValidPercentage\":100},\"RedactedPercentage\":0,\"Scaled\":{\"Flags\":null,\"Reading\":4.809,\"ValidPercentage\":100},\"SensorLabel\":\"FLOW\",\"SensorName\":\"Flow\",\"Slope\":1,\"UniqueId\":685100,\"UnitName\":\"Litres Per Minute\"},{\"Channel\":57,\"DataRate\":60,\"Offset\":0,\"PreScaled\":{\"Flags\":null,\"Reading\":60.43,\"ValidPercentage\":100},\"RedactedPercentage\":0,\"Scaled\":{\"Flags\":null,\"Reading\":60.43,\"ValidPercentage\":100},\"SensorLabel\":\"HUM\",\"SensorName\":\"Humidity\",\"Slope\":1,\"UniqueId\":685100,\"UnitName\":\"Percent\"}],\"Location\":{\"Altitude\":null,\"Latitude\":52.20175,\"Longitude\":-1.7266},\"Timestamp\":{\"Convention\":\"TimeBeginning\",\"Timestamp\":\"2023-05-29T10:23:00+00:00\"}},{\"Channels\":[{\"Channel\":55,\"DataRate\":60,\"Offset\":0,\"PreScaled\":{\"Flags\":null,\"Reading\":4.803,\"ValidPercentage\":100},\"RedactedPercentage\":0,\"Scaled\":{\"Flags\":null,\"Reading\":4.803,\"ValidPercentage\":100},\"SensorLabel\":\"FLOW\",\"SensorName\":\"Flow\",\"Slope\":1,\"UniqueId\":685100,\"UnitName\":\"Litres Per Minute\"}],\"Location\":{\"Altitude\":null,\"Latitude\":52.20175,\"Longitude\":-1.7266},\"Timestamp\":{\"Convention\":\"TimeBeginning\",\"Timestamp\":\"2023-05-29T10:22:00+00:00\"}}]";
ReferenceStationData jsonLatestData = JsonConvert.DeserializeObject<ReferenceStationData>(responseData, new JsonSerializerSettings{DateTimeZoneHandling = DateTimeZoneHandling.Utc});
//holds the desired deserialization logic
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
JObject jo = JObject.Load(reader);
object targetObj = Activator.CreateInstance(objectType);
foreach (PropertyInfo prop in objectType.GetProperties().Where(p => p.CanRead && p.CanWrite))
{
JsonPropertyAttribute att = prop.GetCustomAttributes(true).OfType<JsonPropertyAttribute>().FirstOrDefault();
string jsonPath = att != null ? att.PropertyName : prop.Name;
if (serializer.ContractResolver is DefaultContractResolver)
{
var resolver = (DefaultContractResolver)serializer.ContractResolver;
jsonPath = resolver.GetResolvedPropertyName(jsonPath);
}
if (!Regex.IsMatch(jsonPath, @"^[a-zA-Z0-9_.-]+$"))
{
//throw new InvalidOperationException($"JProperties of JsonPathConverter can have only letters, numbers, underscores, hiffens and dots but name was ${jsonPath}."); // Array operations not permitted
}
JToken token = jo.SelectToken(jsonPath);
if (token != null && token.Type != JTokenType.Null)
{
object value = token.ToObject(prop.PropertyType, serializer);
prop.SetValue(targetObj, value, null);
}
}
return targetObj;
}
Here is my code example;
答案1
得分: 2
将目标类型更改为数组或列表,例如:
var settings = new JsonSerializerSettings{
DateTimeZoneHandling = DateTimeZoneHandling.Utc
};
var stations = JsonConvert.DeserializeObject<ReferenceStationData[]>(
responseData,
settings);
DeserializeObject
将数据反序列化为您指定的确切类型。您需要告诉它将JSON字符串处理为数组或对象,通过指定正确的类型。
英文:
Change the target type to an array or list, eg:
var settings = new JsonSerializerSettings{
DateTimeZoneHandling = DateTimeZoneHandling.Utc
};
var stations= JsonConvert.DeserializeObject<ReferenceStationData[]>(
responseData,
settings);
DeserializeObject
will deserialize the data to the exact type you specify. You need to tell it to handle the JSON string as an array or object by specifying the correct type.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论