How to parse complex JSON object in Unity with C# [duplicate] - c#

This question already has answers here:
Serialize and Deserialize Json and Json Array in Unity
(9 answers)
Closed 4 years ago.
^--- For rebuttal of assertion that question is a mere duplicate, see Note at bottom.
spoiler: see bottom of question for final code based on carldevelopsforcoffee's accepted answer that works.
Original question:
I'm attempting to parse a complex JSON file (see below) using C# in Unity (2018.1, VS2015 if it matters) using UnityEngine.JsonUtility.FromJson(). The parser code is listed below.
The top-level variables (sweepIndex, totalRadials, etc) all parse fine into the Sweep object, but the 'radials' array appears to be getting skipped (the List of Radial objects in Sweep ends up null).
If it's not obvious from the JSON, it has the following structure:
A top-level "Sweep" object with 13 simple values and an array of Radial objects.
Each Radial object in the List has 4 simple values, and an array of doubles
Formatted JSON to illustrate structure:
(edited & truncated for clarity... full JSON is String in class below)
{"sweepIndex":0,
"totalRadials":720,
"beamWidth":0.949999988079071,
"startingUnixtime":1536864392000,
"endingUnixtime":1536863574000,
"totalGatesPerRay":1832,
"gateDepthMeters":250.0,
"distanceToFirstGateMeters":2125.0,
"meanElevationDeg":0.5275726318359375,
"originLatitude":33.989444444444445,
"originLongitude":-78.42888888888889,
"originAltitude":20.0,
"deviantOriginCount":0,
"radials": [
{"radialNumber":0,"azimuthDeg":263.21319580078125,"elevationDeg":0.53009033203125,"duration":66521592,
"gateIntensity":[-5.5,-1.0,1.0,3.0,13.5,-15.0,-13.0,-11.5,-10.5,-7.5]},
{"radialNumber":1,"azimuthDeg":263.7432861328125,"elevationDeg":0.5328369140625,"duration":66521616,
"gateIntensity":[-9.5,-1.0,-4.5,-2.5,5.0,-4.0,9.0,-8.5,-1.5,-9.0]}
]}
I'm the one generating the JSON file (using Netcdf-Java to inhale the raw level-2 radar data and spit it out as JSON for the Unity app to consume), so I could probably change the JSON if it made my life enormously easier... but I'd really prefer to not substantially change the overall structure (Sweep Object with array of Radial Objects with array of doubles).
The class:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using UnityEngine;
namespace Assets.Scripts {
public class RadarData {
private String site;
private Sweep sweep;
public RadarData(String site) {
this.site = site;
String src = #"{""sweepIndex"":0,""totalRadials"":720,""beamWidth"":0.949999988079071,""startingUnixtime"":1536863321000,""endingUnixtime"":1536863574000,""totalGatesPerRay"":1832,""gateDepthMeters"":250.0,""distanceToFirstGateMeters"":2125.0,""meanElevationDeg"":0.5275726318359375,""originLatitude"":33.989444444444445,""originLongitude"":-78.42888888888889,""originAltitude"":20.0,""deviantOriginCount"":0,""radials"":[{""radialNumber"":0,""azimuthDeg"":263.21319580078125,""elevationDeg"":0.53009033203125,""duration"":66521592,""gateIntensity"":[-5.5,-1.0,1.0,3.0,13.5,-15.0,-13.0,-11.5,-10.5,-7.5,-5.0,-3.5,-2.0,-19.5,-13.5,-11.0,-9.0,-6.0,-6.0,-6.0,-6.5,-7.0,-3.5,-4.5,-5.5,-6.5,-13.0,-11.0,-9.5,-11.5,-11.5,-11.0,-10.5,-7.0,-5.0,-3.5,-10.5,-9.5,-9.0,-8.5,-1.0,-1.5,-2.5,-4.0,-6.0,-11.5,-5.5,6.5,-0.5,-10.0,-14.5,-2.5,9.5,5.0,11.0,-1.0,-4.0,-4.0,-4.5,-5.0,-6.0,-7.0,-1.0,6.0,-9.0,-5.5,-9.0,-3.5,3.5,-0.5,14.0,-7.0,14.5,7.0,13.5,0.0,3.0,-6.0,-9.0,-1.5,-0.5,-2.5,2.5,2.0,1.0,0.0,-1.0,-0.5,-3.5,-2.5,5.5,1.5,2.0,-4.5,-7.5,-4.0,-2.0,-2.0,-2.0,-2.0,-2.0,-0.5,0.0,3.5,-8.0,-3.5,-2.5,4.5,-5.0,-2.5,-1.0,-2.0,-2.5,4.5,-3.5,1.5,-6.5,-4.5,-6.5,1.0,-2.5,-2.5,-1.5,-2.0,-0.5,-4.0,1.0,-2.5,-2.0,-5.0,1.5,3.5,2.0,-6.5,2.5,5.0,1.0,4.0,-2.5,-4.5,2.5,-5.5,2.0,-3.5,0.5,0.0,-0.5,3.0,6.5,-7.0,-2.0,0.5,-1.0,3.0,2.0,-1.0,3.0,1.0,1.5,-1.0,-1.0,5.0,-1.0,2.5,-5.0,-2.0,-7.5,5.5,0.0,-1.5,2.5,2.0,2.5,4.5,1.0,-1.5,3.5,1.5,2.5,5.0,-4.0,0.5,-1.0,6.0,3.0,2.0,5.0,-2.0,-1.5,5.5,5.0,4.0,3.5,2.5,1.5,1.5,-1.5,2.5,-2.0,0.5,-1.0,-1.0,-1.0,0.5,-2.5,0.0,-1.5,-0.5,0.5,3.0,0.5,0.5,-3.0,-2.5,-2.0,-2.0,-1.5,0.5,-4.5,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-3.0,-2.0,-4.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-2.5,-3.0,-1.0,0.5,-1.5,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,0.5,2.0,-3.0,-1.0,-1.5,-3.5,-2.0,-1.0,-1.0,-2.0,-1.0,-1.0,-1.0,-1.0,0.5,-1.5,1.5,-1.0,-1.0,-1.0,-0.5,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0]},{""radialNumber"":1,""azimuthDeg"":263.7432861328125,""elevationDeg"":0.5328369140625,""duration"":66521616,""gateIntensity"":[-9.5,-1.0,-4.5,-2.5,5.0,-4.0,9.0,-8.5,-1.5,-9.0,-13.5,-0.5,-4.5,-14.0,-4.5,-11.0,-9.0,-8.0,-7.0,-6.0,-5.0,-3.0,-7.0,-10.0,-11.5,-10.0,-7.0,-8.5,-11.0,-13.0,-5.5,-5.0,-7.0,-10.0,-7.5,-10.5,-11.0,-11.0,-11.5,-12.5,-5.0,-6.0,-6.5,-7.0,-8.0,-9.0,-3.5,4.5,4.5,-8.5,-8.5,-2.0,13.0,9.5,1.0,-4.5,-0.5,-4.5,-5.5,1.0,0.5,-0.5,-2.0,-4.5,-9.5,-0.5,4.5,-13.0,-0.5,1.0,2.5,3.5,4.5,3.5,2.0,0.0,-5.5,-4.5,1.0,-0.5,3.0,-6.5,-3.5,-1.5,0.0,1.0,2.0,-2.0,-3.0,-4.5,-5.0,-5.5,-6.0,-7.0,-7.0,-6.5,-6.5,-6.0,-4.5,-3.0,-2.0,4.0,-2.5,-0.5,-9.0,-4.0,3.0,4.5,6.5,4.5,-1.5,-3.5,4.0,-1.0,0.0,5.0,1.0,-4.0,-1.0,-2.0,-0.5,-4.0,-0.5,1.0,3.5,0.0,1.0,-6.0,-1.5,-5.5,-5.5,-5.5,-5.5,-5.5,2.0,1.5,4.5,3.0,2.5,0.0,2.0,-7.5,8.0,-1.5,0.5,-1.5,2.0,2.5,3.5,3.5,2.0,0.5,-0.5,-1.5,-1.0,0.0,0.0,2.0,-0.5,-2.5,-6.0,5.0,2.5,3.0,-5.5,-1.0,-4.0,4.5,1.0,-2.5,4.0,-3.0,-1.5,-0.5,0.0,1.0,-2.0,-2.5,-0.5,-7.0,4.5,4.5,3.0,-0.5,-6.5,-1.0,1.5,3.0,4.0,6.0,5.5,5.0,4.0,3.5,2.0,1.5,-4.0,2.0,0.5,1.0,-0.5,2.5,2.0,0.5,-2.0,-1.5,-1.0,-4.0,-5.5,-0.5,2.5,-5.0,0.0,-4.5,4.5,0.5,-2.0,1.5,-1.0,-3.5,1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.5,-3.0,-1.5,-1.0,-1.0,-1.0,-1.0,-1.5,-2.5,1.5,-3.5,-3.5,-1.0,-1.0,-1.0,-3.5,1.5,0.5,-3.5,-1.0,-2.0,-1.5,-4.0,-3.5,-1.0,-1.0,-1.0,-1.0,-0.5,0.0,-1.0,-1.0,-1.0,-3.0,-4.0,-1.0,-1.0,-1.0,-3.5,1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-3.5,-2.0,1.5,-1.0,0.0,-3.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0]}]}";
this.sweep = JsonUtility.FromJson<Sweep>(src);
}
public String toString() {
StringBuilder s = new StringBuilder();
s.AppendFormat("{0} at ({1},{2}), elevation={3}m\n", site, sweep.originLatitude, sweep.originLongitude, sweep.originAltitude);
foreach (Radial r in sweep.radials) {
s.AppendFormat("\tRadial #{0} -- az={1}, el={2}\n", r.radialNumber, r.azimuthDeg, r.elevationDeg);
}
return s.ToString();
}
}
public class Sweep {
public int sweepIndex;
public int totalRadials;
public float beamWidth;
public long startingUnixtime;
public long endingUnixtime;
public int totalGatesPerRay;
public float gateDepthMeters;
public float meanElevationDeg;
public double originLatitude;
public double originLongitude;
public float originAltitude;
public int deviantOriginCount;
public List<Radial> radials;
}
public class Radial {
public int radialNumber;
public float azimuthDeg;
public float elevationDeg;
public long duration;
public List<double> gateIntensity;
}
}
Note:
The question for which the user "Programmer" has stated that this is an alleged duplicate has an answer that doesn't actually solve my stated problem -- complex JSON in Unity. It establishes that Unity's built in JsonUtility class is inadequate for parsing complex JSON, while offering no real alternative.
There are questions on SO about using third-party Json libraries with C#... but using third-party libraries with C# in a Unity project is considerably harder and more specific of a task if they aren't already available as a .unitypackage, especially if it needs to be capable of ultimately working on platforms besides Windows (eg, Android, Magic Leap, Oculus, etc).
That's why the accepted answer to this question is valuable & adds concrete value to SO as a resource... it identifies a solution that addresses the questions's three specific issues -- complex Json, C#, and getting it to work in Unity in a platform-agnostic manner.
Final working code (based on accepted answer)
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using UnityEngine;
using JsonFx.Json;
using UnityEditor;
namespace Assets.Scripts {
public class RadarData {
private String site;
private Sweep sweep;
public RadarData(String site) {
this.site = site;
TextAsset src = AssetDatabase.LoadAssetAtPath("Assets/RadarData/" + site + ".json", typeof(TextAsset)) as TextAsset;
var reader = new JsonReader();
dynamic output = reader.Read(src.ToString());
sweep = new Sweep();
sweep.sweepIndex = output["sweepIndex"];
sweep.beamWidth = (float) output["beamWidth"];
sweep.startingUnixtime = output["startingUnixtime"];
sweep.endingUnixtime = output["endingUnixtime"];
sweep.totalGatesPerRay = output["totalGatesPerRay"];
sweep.gateDepthMeters = (float)(output["gateDepthMeters"]);
sweep.meanElevationDeg = (float)(output["meanElevationDeg"]);
sweep.originLatitude = (float)(output["originLatitude"]);
sweep.originLongitude = (float)(output["originLongitude"]);
sweep.originAltitude = (float)(output["originAltitude"]);
sweep.deviantOriginCount = output["deviantOriginCount"];
Dictionary<String,object>[] radials = output["radials"];
sweep.setRadials(radials);
}
public Sweep getSweep(int sweepNumber) {
return sweep;
}
public String toString() {
return sweep.ToString();
}
}
public class Sweep {
public int sweepIndex;
public int totalRadials;
public float beamWidth;
public long startingUnixtime;
public long endingUnixtime;
public int totalGatesPerRay;
public float gateDepthMeters;
public float meanElevationDeg;
public float originLatitude;
public float originLongitude;
public float originAltitude;
public int deviantOriginCount;
public List<Radial> radials;
public void setRadials(Dictionary<String,object>[] src) {
radials = new List<Radial>();
foreach (Dictionary<String,object> rad in src) {
radials.Add(new Radial(rad));
}
}
override public String ToString() {
StringBuilder s = new StringBuilder();
s.AppendFormat("Sweep[index={0}... {1} Radials]", sweepIndex, radials.Count());
return s.ToString();
}
}
public class Radial {
public int radialNumber;
public double azimuthDeg;
public double elevationDeg;
public long duration;
public double[] gateIntensity;
public Radial(Dictionary<String,object> d) {
radialNumber = (int)(d["radialNumber"]);
azimuthDeg = (double)(d["azimuthDeg"]);
elevationDeg = (double)(d["elevationDeg"]);
duration = long.Parse(d["duration"].ToString());
gateIntensity = (double[])(d["gateIntensity"]);
}
}
}

Copy paste your json and http://json2csharp.com/
You will get this:
public class Radial
{
public int radialNumber { get; set; }
public double azimuthDeg { get; set; }
public double elevationDeg { get; set; }
public int duration { get; set; }
public List<double> gateIntensity { get; set; }
}
public class RootObject
{
public int sweepIndex { get; set; }
public int totalRadials { get; set; }
public double beamWidth { get; set; }
public long startingUnixtime { get; set; }
public long endingUnixtime { get; set; }
public int totalGatesPerRay { get; set; }
public double gateDepthMeters { get; set; }
public double distanceToFirstGateMeters { get; set; }
public double meanElevationDeg { get; set; }
public double originLatitude { get; set; }
public double originLongitude { get; set; }
public double originAltitude { get; set; }
public int deviantOriginCount { get; set; }
public List<Radial> radials { get; set; }
}
Then you can use the JsonUtility but you first need to modify some content.
Add Serializable attribute to each class and remove the property extension to make those basic variables.
[Serializable]
public class Radial
{
public int radialNumber;
public double azimuthDeg;
public double elevationDeg;
public int duration;
public List<double> gateIntensity;
}
[Serializable]
public class RootObject
{
public int sweepIndex;
// same with all following items
}
RootObject is the top class of your json, it has no name in the json so default is generated. You can change RootObject to anything you want like JsonResponse.
This is now ready to use like this:
void Start()
{
string json = GetJsonFile(); // From download or text file
RootObject ro = JsonUtility.FromJson<RootObject>(json);
print( ro.radials[0].radialNumber);
}

I use JsonFx for my data classes in Unity.
Example Class:
using JsonFx.Json;
[Serializable]
[JsonName("MyData")]
public class MyData
{
public int id;
public string name;
public int[] stuff;
}
Sample json:
{
"__Type": "MyData, Assembly-CSharp",
"id": 1,
"name": "new_data",
"stuff" :
[
0,
1,
2
]
}
Creating your data object from json :
// Json to MyData object:
// Assume I downloaded a json file
string jsonData = System.Text.Encoding.UTF8.GetString (www.bytes);
jsonData = jsonData.Trim ();
MyData data = MyData.Deserialize(jsonData);
Creating your json file from a data object
// MyData object to Json
// Use MyData data object
string file = "mydata.json";
JsonWriterSettings settings = new JsonWriterSettings ();
settings.PrettyPrint = true;
settings.TypeHintName = "__Type";
JsonWriter writer = new JsonWriter (file, settings);
writer.Write (data);
writer.TextWriter.Flush ();
writer.TextWriter.Close ();

There is an online service that can auto-convert from Json to Poco, for instance
http://json2csharp.com/
http://jsonutils.com/
https://quicktype.io/
In VisualStudio, there is also a menu that does so:

Related

Edit GeoJson file in asp.net core C#

I want to edit GeoJson file, which I put part of its lines here. How to edit in this way, I have to read the file and change the Landuse value using the code in the properties.
{"type":"FeatureCollection", "features": [
{"type":"Feature","geometry":{"type":"Polygon","coordinates":[[[45.882982627281955,35.98144306876872],[45.8830448154499,35.98142063110326],[45.883106013386524,35.98143674855534],[45.883177395327635,35.981590195979166],[45.88306057502328,35.98161790966196],[45.882982627281955,35.98144306876872]]]},"properties":{"Code":1,"Landuse":"مسکونی","Longitude":45.8830793043,"latitude":35.9815185013}},
{"type":"Feature","geometry":{"type":"Polygon","coordinates":[[[45.88321822952168,35.98143433703011],[45.88329577844585,35.981578778123584],[45.883184747057655,35.98160599975271],[45.883177395327635,35.981590195979166],[45.88313701140243,35.981503383976175],[45.883107851319025,35.981440699498734],[45.88321822952168,35.98143433703011]]]},"properties":{"Code":2,"Landuse":"مسکونی","Longitude":45.8832014571,"latitude":35.9815182472}},
...
]}
I converted the GeoJson file to C# classes using this site.
And the result is as follows
public class ConvertorJsonLayerDTO {
public class Feature {
public string type {
get;
set;
}
public Geometry geometry {
get;
set;
}
public Properties properties {
get;
set;
}
}
public class Geometry {
public string type {
get;
set;
}
public List<List<List<double>>> coordinates {
get;
set;
}
}
public class Properties {
public int Code {
get;
set;
}
public string Landuse {
get;
set;
}
public double Longitude {
get;
set;
}
public double latitude {
get;
set;
}
}
public class Root {
public string type {
get;
set;
}
public List<Feature>features {
get;
set;
}
}
}
Now I read the file in C# as follows:
var code = 2;
var Geojson = File.ReadAllText(Path);
var deserialize = JsonConvert.DeserializeObject<Root>(Geojson);
Now, how do I make a blind move on this file and change the property whose code is 2 to the Landuse property value and update the file?
Please guide me. I will definitely share the result with you...Thankful
I'd recomend using Linq:
var feature = deserialize.features.FirstOrDefault(feature => feature.properties.Code == 2);
if (feature != null)
{
feature.properties.Landuse = "new Landuse";
}
It gives you the first feature where feature.properties.Code is equal to 2 or it returns null if there is no feature with the code 2.
You could Try with JObject to avoid unnecessary models/Properties for rest part of your file
var str= System.IO.File.ReadAllText("path");
var jobj= JObject.Parse(str);
var newjobj= (JObject)jobj["SomeSection"]["ChildSection"];
var obj = newjobj.ToObject<TargetObject>();
enter image description here
I did the same but got this error
I'm just looking for a solution to query a GeoJson file and edit the desired value and save it again.

Newtonsoft.Json parsing json from webpage doesn't work

I've made a simple program that gets json from a website. It should give out some of the json attributes, but it doesn't do it. It simply gives me a clear String without text in it. Can someone help me?
My Code:
using System;
using System.Linq;
using System.Diagnostics;
using System.Threading;
using System.Net;
using System.IO;
using Newtonsoft.Json;
namespace ESEL_Scraper_2._0
{
class MyJsonType
{
public string title { get; set; }
public int id { get; set; }
}
class Program
{
static void Main(string[] args)
{
WebClient client = new WebClient();
client.Encoding = System.Text.Encoding.UTF8;
string site = client.DownloadString($"https://esel.at/api/termine/data?date=05.09.2020&selection=false");
var myJsonObject = JsonConvert.DeserializeObject<MyJsonType>(site);
Console.WriteLine(myJsonObject.title);
}
}
}
The JSON: https://esel.at/api/termine/data?date=05.09.2020&selection=false
MyJsonType expects the body to be like,
{
"id": 1,
"title": "title"
}
but in your case, the json is,
{
"termine": [
{ -> object }
{ -> object }
]
}
You have an array of Objects that fit into your MyJsonType. Use the following class to deserialize to
public class RootObject
{
[JsonProperty("termine")] // the name of the property is case sensetive.
public List<MyJsonType> Termine {get;set;}
}
public class MyJsonType
{
[JsonProperty("title")]
public string Title { get; set; } //C# uses uppercase first letter for properties.
[JsonProperty("id")]
public int Id { get; set; }
}
// in your main,
var obj = JsonConvert.DeserializeObject<RootObject>(json);
Console.WriteLine(obj.Termine.First().Title);
You need to structure your call as per your json string.
You class should look like this
public class ParentJsonType
{
public List<MyJsonType> termine { get; set; }
}
public class MyJsonType
{
public string title { get; set; }
public int id { get; set; }
}
and in your code you can deserialize
WebClient client = new WebClient();
client.Encoding = System.Text.Encoding.UTF8;
string site = client.DownloadString($"https://esel.at/api/termine/data?date=05.09.2020&selection=false");
var myJsonObject = JsonConvert.DeserializeObject<List<MyJsonType>>(site);
foreach(var myJosnType in myJsonObject)
{
//add your logic here
Console.WriteLine(myJosnType.title);
}
Yes, guys that already answered are absolutely right.
The point is in the wrong model you have, which has no necessary structure to contain a responded context.
The following approach is also working. The correct model for that JSON should be:
public class Termine
{
public Int64 id {get;set;}//":106102,
public String title {get;set;}//":"curated by 2020",
public String category {get;set;}//":"eSeLs Neugierde",
public String startdate {get;set;}//":"Sa, 05.09.2020",
public String startdatetime {get;set;}//":"Sa, 05.09. 11:00",
public String starttime {get;set;}//":"11:00",
public String enddate {get;set;}//":"Sa, 05.09.2020",
public List<object> runtime {get;set;}//":[ 0, "nur noch heute" ],
public String thumbnail {get;set;}//":"https:\/\/static.esel.at\/mini\/\/upload\/IpeP5wgYL7sRucTuFtpJg53zgG7hby5IiXv5txLk.jpeg",
public String thumbnail_credits {get;set;}//":null,
public String type {get;set;}//":"upcoming",
public String recommended {get;set;}//":"(Wie) Schafft's Kunst als Aktivismus in Galerier\u00e4ume?`",
public Boolean online_event {get;set;}//":false,
public String feed_urls {get;set;}//":null,
public String status {get;set;}//":"",
public String tags {get;set;}//":"Galerienfestival, internationale KuratorInnen, Aktivismus, Kunst, curatedby",
public String url {get;set;}//":"https:\/\/esel.at\/termin\/106102\/curated-by-2020",
public DateTime sort_date {get;set;}//":"2020-09-05 11:00:00",
public String sort_category {get;set;}//":"eselsneugierde",
public String location_url {get;set;}//":"https:\/\/esel.at\/location\/933\/wien",
public String location {get;set;}//":"Wien"
public override String ToString(){
return String.Format("[{0}] {1} ({2})", this.id, this.title, this.location_url);
}
}
public class Meta
{
public List<String> next {get;set;}//":[ "Sonntag,<br><nobr>06. September 2020<\/nobr>", "06.09.2020", "06092020" ],
public DateTime now {get;set;}//":"2020-09-05T18:52:05.000040Z",
public List<String> da {get;set;}//":[ "Samstag,<br><nobr>05. September 2020<\/nobr>", "05.09.2020", "05092020" ],
public DateTime end {get;set;}//":"2020-09-05T21:59:59.999999Z",
public DateTime runtime {get;set;}//":"2020-09-04T22:00:00.000000Z",
public Int32 upcoming {get;set;}//":14
public Int32 running {get;set;}//":87,
public Int64 termine {get;set;}//":16
}
public class Context
{
public List<Termine> termine{get;set;}
public Meta meta {get;set;}
}
So, your code will work with a few changes:
public static void Main(string[] args)
{
WebClient client = new WebClient()
{
Encoding = System.Text.Encoding.UTF8
};
string site = client.DownloadString("https://esel.at/api/termine/data?date=05.09.2020&selection=false");
Context ctx = JsonConvert.DeserializeObject<Context>(site);
ctx.termine.ForEach(Console.WriteLine);
}
Here is the link to the full solution where you can run and test.
https://dotnetfiddle.net/elq5Lv

Deserialize json data into list in c#

I am calling an external web service and this is what I get in response after posting to their server:
{
"status":200,
"data":{
"h21":{
"total_price":{
"acacia":{
"available":0,
"price":null,
"availability":false
},
"maple":{
"available":7,
"price":2399.0,
"availability":true
}
}
},
"h17":{
"total_price":{
"mahogany":{
"available":1,
"price":1899.0,
"availability":true
},
"oak":{
"available":0,
"price":null,
"availability":false
},
"maple":{
"available":6,
"price":1649.0,
"availability":true
}
}
}
}
}
I want this response to be converted into a list. I used jsontocsharp online converter to generate class and use code below:
var Jsonresult = JsonConvert.DeserializeObject<Sstageback.Models.Sstage.treeboRoomTypes.RootObject>(JsonReplace);
But the thing is mine is a dynamic JSON response which can change over course of time.
Note: The response which I get from the server is hotel and its room availability so while generating classes I can't generate with a single class file since the hotel id's may change also the room types and its availability also changes.
Example: h21 is one hotel id and total_price has its room type details similarly h17 is the next hotel and total_price has its room type details.
Basically, TotalPrice should be a Dictionary<string, Availability> or similar. It's not clear what list you'd have, but that's naturally a dictionary. That's then nested within a dictionary at the top level.
Sample code:
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using Newtonsoft.Json;
public class Response
{
public int Status { get; set; }
public Dictionary<string, Hotel> Data { get; set; }
}
public class Hotel
{
[JsonProperty("total_price")]
public Dictionary<string, Room> TotalPrice { get; set; }
}
public class Room
{
public int Available { get; set; }
public decimal? Price { get; set; }
public bool Availability { get; set; }
}
class Test
{
static void Main(string[] args)
{
var text = File.ReadAllText("test.json");
var response = JsonConvert.DeserializeObject<Response>(text);
foreach (var pair in response.Data)
{
Console.WriteLine($"Key: {pair.Key}");
foreach (var nestedPair in pair.Value.TotalPrice)
{
var room = nestedPair.Value;
Console.WriteLine($" {nestedPair.Key}: {room.Available}/{room.Price}/{room.Availability}");
}
}
}
}
Output:
Key: h21
acacia: 0//False
maple: 7/2399.0/True
Key: h17
mahogany: 1/1899.0/True
oak: 0//False
maple: 6/1649.0/True
You'll need to make a DTO model that corresponds with the response. The value of a attribute can change, that's no problem, as long as the type stays the same ( an int stays an int and a string stays a string).
Your Object could look like this:
public class Room{
public int Available { get; set;}
public int Price { get; set; }
public bool availability { get; set; }
}
public class Hotel{
public string Name { get; set; }
public List<Room> Rooms { get; set; }
}
You should convert Serialize and Deserialize this. This is only an example, you want your model to be 100% the same as your JSON.
For an easy conversion between Models and DTO, you could use AutoMapper: http://automapper.org/

No serializer defined for type: System.Windows.Media.Media3D.Point3D

I am trying to serialize some data using protobuf net. During the serialization I am getting an error that No serialization defined for the type Point3D. I found one issue something like this but still unable to implement and resolve it. Link is as follow :- No serializer defined for type: System.Drawing.Color
[ProtoContract]
public class ReturnPanelData
{
[ProtoMember(1)]
public Point3D PlacedPoint3D { get; set; }
[ProtoMember(2)]
public double PlacementAngle { get; set; }
[ProtoMember(3)]
public string PanelName { get; set; }
}
[ProtoContract]
public class ReturnDataType
{
[ProtoMember(1)]
public List<ReturnPanelData> ReturnList { get; set; }
[ProtoMember(2)]
public double RemainderArea { get; set; }
[ProtoMember(3)]
public int Height { get; set; }
[ProtoMember(4)]
public int Width { get; set; }
[ProtoMember(5)]
public Point3D BasePoint3D { get; set; }
}
class Program
{
private static HashSet<ReturnDataType> _processedList = new HashSet<ReturnDataType>();
static void Main(string[] args)
{
using (var file = File.Create(#"D:\SavedPCInfo2.bin"))
{
Serializer.Serialize(file, _processedList);
}
Console.WriteLine("Done");
}
}
I am a begineer in JSON serialization/deserialization. How to resolve this issue ?
If it is not possible to serialize Point3D with Protobuf Net, what are the other options to serialize/deserialize a very big list (having approx 300000 items) ?
First off, protobuf-net is not a JSON serializer. It serializes from and to "Protocol Buffers" - the binary serialization format used by Google for much of their data communications.
That being said, there are several solutions to serialize a type, using protobuf-net, that cannot be decorated with ProtoContract attributes:
When contained by some other type, use a proxy or "shim" property as is shown here, OR
Use a surrogate as is shown here, OR
In runtime teach the RuntimeTypeModel about all serializable fields & properties of the type as described here in the section Serializing without attributes.
For option 2, Since a Point3D is entirely defined by its X, Y and Z coordinates, it's very easy to introduce a serialization surrogate:
[ProtoContract]
struct Point3DSurrogate
{
public Point3DSurrogate(double x, double y, double z) : this()
{
this.X = x;
this.Y = y;
this.Z = z;
}
[ProtoMember(1)]
public double X { get; set; }
[ProtoMember(2)]
public double Y { get; set; }
[ProtoMember(3)]
public double Z { get; set; }
public static implicit operator Point3D(Point3DSurrogate surrogate)
{
return new Point3D(surrogate.X, surrogate.Y, surrogate.Z);
}
public static implicit operator Point3DSurrogate(Point3D point)
{
return new Point3DSurrogate(point.X, point.Y, point.Z);
}
}
And then register it with protobuf-net just once on startup like so:
ProtoBuf.Meta.RuntimeTypeModel.Default.Add(typeof(Point3D), false).SetSurrogate(typeof(Point3DSurrogate));
Alternatively, for option 3, in startup you could define a contract for Point3D like so:
ProtoBuf.Meta.RuntimeTypeModel.Default.Add(typeof(Point3D), true);
ProtoBuf.Meta.RuntimeTypeModel.Default[typeof(Point3D)].Add(1, "X").Add(2, "Y").Add(3, "Z");
(In my opinion the surrogate is clearer despite requiring more code; defining the protocol entirely in runtime seems too fiddly.)
I don't recommend option 1 since you would need to add proxy properties to all classes that use Point3D.

Load object data from XML in C#

I have the following class:
[Serializable]
public class SerialAssassin
{
public Hero hero;
public Point heroPB;
public Boss boss;
public Point bossPB;
public Attack attack;
public Point attackPB;
public HPMeter bossHP;
public Point bossHPPB;
public PPMeter heroPP;
public Point heroPPPB;
public Rectangle bossRect;
public Rectangle attackRect;
public int heroState;
public int stepRate;
public int attackDirection;
public int attackLoop;
public int contadorPaso;
public int contadorPasoBoss;
public int bossTop, bossLeft;
public int bossState;
public int bossHealth;
public int bossHPCap;
public int opa;
public int battlesWon;
public int mainBossCounter;
public int ppleft;
public bool paso;
public bool inStadium;
public bool fading;
public bool fightingMainBoss;
public bool fainted;
public string currentPokemon;
}
I'm having problems reading the data from the XML, which was written as follows:
XmlSerializer serializer = new XmlSerializer(typeof(SerialAssassin));
TextWriter textWriter = new StreamWriter(#"..\..\Resources\saveState.xml");
serializer.Serialize(textWriter, serial);
textWriter.Close();
From there, I don't quite know how to read the data. Plus the fact that the XML doesn't serialize the objects of Hero, Boss, Attack, HPMeter, PPMeter.
Hero class:
public class Hero
{
int state = 0;
int x, y;
string path;
Image img;
//methods
}
I'd be grateful if you would be so kind as to explain to me how to load those objects/primitives and then use them.
IIRC, the XmlSerializer checks for properties, not fields. (I think it can use public fields, but you really ought to switch to properties anyway) In addition, classes do not need to be marked as Serializable. (Serializable is used for others such as binary and SOAP serializers)
Replace your fields with properties with public getters and setters. In addition, make sure your other classes (such as Hero, Point, Boss) are all also serializable according to XmlSerializer's rules:
public class SerialAssassin
{
public Hero hero { get; set; }
public Point heroPB { get; set; }
public Boss boss { get; set; }
public int heroState { get; set; }
...
To deserialize, use its Deserialize method (http://msdn.microsoft.com/en-us/library/system.xml.serialization.xmlserializer.deserialize.aspx):
Stream xmlInputStream = ... //get your file stream, or TextReader, or XmlReader
XmlSerializer deserializer = new XmlSerializer(typeof(SerialAssassin));
SerialAssassin assassin = (SerialAssassin)deserializer.Deserialize(xmlInputStream)
EDIT: Looking at your sample Hero class, it's not serializing any of its values because you have declared them all to be private. Make them public instead.
public class Hero
{
public int state {get; set; }
public int x { get; set; }
public int y { get; set; }
public string path { get; set; }
[XmlIgnore]
public Image img { get; set; }
}
I suspect that Image will not be serializable, so you may want to store the image's file path (or some other identifying information) so you can save/load it. [XmlIgnore] will instruct the XmlSerializer to ignore that property so it doesn't fail during serialization/deserialization.
XmlSerializer serializer = new XmlSerializer(typeof(SerialAssassin));
SerialAssassin assassin;
using(var reader = File.OpenText(#"..\..\Resources\saveState.xml"))
{
assassin = (SerialAssassin)serializer.Deserialize(reader);
}

Categories

Resources