unity3d 反序列化JSON(没有动态),其中数组基于另一个属性的值具有多个可能的深度?

h7wcgrx3  于 2023-06-30  发布在  其他
关注(0)|答案(2)|浏览(189)

我尝试在不使用dynamic的情况下反序列化以下JSON,因为我的系统不支持它:https://raw.githubusercontent.com/vansha/Two10.CountryLookup/master/Two10.CountryLookup/region-list.json
每条线表示用于地理定位的区域。
在这里使用JSON转换器:https://json2csharp.com/
我对数据类的建议如下:

// Root myDeserializedClass = JsonConvert.DeserializeObject<RegionJsonObject>(myJsonResponse);

    public class Geometry {
        public string type { get; set; }
        public List<List<List<List<double>>>> coordinates { get; set; }
    }

    public class Properties {
        public string name { get; set; }
        public string type { get; set; }
    }

    public class RegionJsonObject {
        public string type { get; set; }
        public Properties properties { get; set; }
        public Geometry geometry { get; set; }
        public string id { get; set; }
    }

问题是,如果您查看JSON,实际上coordinates数组有两种可能的格式。如果Geometry.typePolygon,我们有三层深度[[[ ]]],如果是MultiPolygon,我们得到四层深度[[[[ ]]]]。因此,我转而考虑使用自定义JsonConverter的以下格式:

class GeometryConverter : JsonConverter {
        public override bool CanConvert(Type objectType) {
            return (objectType == typeof(Geometry));
        }

        public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) {

            Geometry geometry = new Geometry();

            JObject jo = JObject.Load(reader);
            geometry.type = jo["type"].Value<string>();

            if (geometry.type == "Polygon") {
                geometry.coordinatesPolygon = jo["coordinates"].Value<List<List<List<double>>>>(); //DOESN'T WORK
            }
            else {
                geometry.coordinatesMulipolygon = jo["coordinates"].Value<List<List<List<List<double>>>>>(); //DOESN'T WORK
            }

            return geometry;
        }

        public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) {
            // If you want to support serializing you could implement this method as well
            throw new NotImplementedException();
        }
    }

    public class Geometry {
        public string type { get; set; }
        public List<List<List<List<double>>>> coordinatesMulipolygon { get; set; } //multipolygon
        public List<List<List<double>>> coordinatesPolygon { get; set; } //polygon
    }

    public class Properties {
        public string type { get; set; }
        public string name { get; set; }
    }

    public class RegionJsonObject {
        public string type { get; set; }
        public string id { get; set; }
        public Properties properties { get; set; }

        [JsonProperty("geometry")]
        [JsonConverter(typeof(GeometryConverter))] 
        public Geometry geometry { get; set; }
    }

}

但是,这是行不通的。尝试以这种方式设置geometry.coordinatesPolygongeometry.coordinatesMultipolygon会出现错误:
InvalidCastException: Cannot cast Newtonsoft.Json.Linq.JArray to Newtonsoft.Json.Linq.JToken.
我的方法是否正确?如何根据需要将JSON中的数组放入这两个列表对象中?有没有更好或更合适的方法?
谢谢你的帮助

c9x0cxw0

c9x0cxw01#

你可能应该为你的几何体使用多态性:一个类Polygon和一个类Multipolygon。然后你可以使用JsonSubTypes转换器。
你也有一个stackoverflow帖子here

svdrlsy4

svdrlsy42#

if (geometry.type == "Polygon") {
                geometry.coordinatesPolygon = jo["coordinates"].ToObject<List<List<List<double>>>>(); //WORKS
            }
            else {
                geometry.coordinatesMulipolygon = jo["coordinates"].ToObject<List<List<List<List<double>>>>>(); //WORKS
            }

这解决了它。

相关问题