JsonConvert.DeserializeObject – 当前的 JsonReader 项不是一个对象: StartArray

huangapple go评论78阅读模式
英文:

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).

&#39;Error reading JObject from JsonReader. Current JsonReader item is not an object: StartArray. Path &#39;&#39;, line 1, position 1.&#39;

Here is Json response;

var responseData = &quot;[{\&quot;Channels\&quot;:[{\&quot;Channel\&quot;:55,\&quot;DataRate\&quot;:60,\&quot;Offset\&quot;:0,\&quot;PreScaled\&quot;:{\&quot;Flags\&quot;:null,\&quot;Reading\&quot;:4.809,\&quot;ValidPercentage\&quot;:100},\&quot;RedactedPercentage\&quot;:0,\&quot;Scaled\&quot;:{\&quot;Flags\&quot;:null,\&quot;Reading\&quot;:4.809,\&quot;ValidPercentage\&quot;:100},\&quot;SensorLabel\&quot;:\&quot;FLOW\&quot;,\&quot;SensorName\&quot;:\&quot;Flow\&quot;,\&quot;Slope\&quot;:1,\&quot;UniqueId\&quot;:685100,\&quot;UnitName\&quot;:\&quot;Litres Per Minute\&quot;},{\&quot;Channel\&quot;:57,\&quot;DataRate\&quot;:60,\&quot;Offset\&quot;:0,\&quot;PreScaled\&quot;:{\&quot;Flags\&quot;:null,\&quot;Reading\&quot;:60.43,\&quot;ValidPercentage\&quot;:100},\&quot;RedactedPercentage\&quot;:0,\&quot;Scaled\&quot;:{\&quot;Flags\&quot;:null,\&quot;Reading\&quot;:60.43,\&quot;ValidPercentage\&quot;:100},\&quot;SensorLabel\&quot;:\&quot;HUM\&quot;,\&quot;SensorName\&quot;:\&quot;Humidity\&quot;,\&quot;Slope\&quot;:1,\&quot;UniqueId\&quot;:685100,\&quot;UnitName\&quot;:\&quot;Percent\&quot;}],\&quot;Location\&quot;:{\&quot;Altitude\&quot;:null,\&quot;Latitude\&quot;:52.20175,\&quot;Longitude\&quot;:-1.7266},\&quot;Timestamp\&quot;:{\&quot;Convention\&quot;:\&quot;TimeBeginning\&quot;,\&quot;Timestamp\&quot;:\&quot;2023-05-29T10:23:00+00:00\&quot;}},{\&quot;Channels\&quot;:[{\&quot;Channel\&quot;:55,\&quot;DataRate\&quot;:60,\&quot;Offset\&quot;:0,\&quot;PreScaled\&quot;:{\&quot;Flags\&quot;:null,\&quot;Reading\&quot;:4.803,\&quot;ValidPercentage\&quot;:100},\&quot;RedactedPercentage\&quot;:0,\&quot;Scaled\&quot;:{\&quot;Flags\&quot;:null,\&quot;Reading\&quot;:4.803,\&quot;ValidPercentage\&quot;:100},\&quot;SensorLabel\&quot;:\&quot;FLOW\&quot;,\&quot;SensorName\&quot;:\&quot;Flow\&quot;,\&quot;Slope\&quot;:1,\&quot;UniqueId\&quot;:685100,\&quot;UnitName\&quot;:\&quot;Litres Per Minute\&quot;}],\&quot;Location\&quot;:{\&quot;Altitude\&quot;:null,\&quot;Latitude\&quot;:52.20175,\&quot;Longitude\&quot;:-1.7266},\&quot;Timestamp\&quot;:{\&quot;Convention\&quot;:\&quot;TimeBeginning\&quot;,\&quot;Timestamp\&quot;:\&quot;2023-05-29T10:22:00+00:00\&quot;}}]&quot;;

ReferenceStationData jsonLatestData = JsonConvert.DeserializeObject&lt;ReferenceStationData&gt;(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 =&gt; p.CanRead &amp;&amp; p.CanWrite))
		{
			JsonPropertyAttribute att = prop.GetCustomAttributes(true).OfType&lt;JsonPropertyAttribute&gt;().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, @&quot;^[a-zA-Z0-9_.-]+$&quot;))
			{
			//throw new InvalidOperationException($&quot;JProperties of JsonPathConverter can have only letters, numbers, underscores, hiffens and dots but name was ${jsonPath}.&quot;); // Array operations not permitted
			}

			JToken token = jo.SelectToken(jsonPath);
			if (token != null &amp;&amp; token.Type != JTokenType.Null)
			{
				object value = token.ToObject(prop.PropertyType, serializer);
				prop.SetValue(targetObj, value, null);
			}
		}

		return targetObj;
	}

Here is my code example;

https://dotnetfiddle.net/wEUZ83

答案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&lt;ReferenceStationData[]&gt;(
    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.

huangapple
  • 本文由 发表于 2023年7月5日 01:17:53
  • 转载请务必保留本文链接:https://go.coder-hub.com/76614737.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定