Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/278.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 将JSON反序列化为多个数据类型(地理空间系统)_C#_Json_Polymorphism_Deserialization_Core - Fatal编程技术网

C# 将JSON反序列化为多个数据类型(地理空间系统)

C# 将JSON反序列化为多个数据类型(地理空间系统),c#,json,polymorphism,deserialization,core,C#,Json,Polymorphism,Deserialization,Core,在搜索了SO和谷歌的答案后,我不知所措,所以希望有人能在这方面帮助我 我有一个使用第三方API数据的项目。数据是包含资产位置(lat和lng)的JSON消息 但API可以支持多边形和点(分别如下所示): 有一点是这样的: { "geom": { "coordinates": [ -0.00203667, 51.51020028 ], "type

在搜索了SO和谷歌的答案后,我不知所措,所以希望有人能在这方面帮助我

我有一个使用第三方API数据的项目。数据是包含资产位置(lat和lng)的JSON消息

但API可以支持多边形和点(分别如下所示):

有一点是这样的:

{
    "geom": {
        "coordinates": [
            -0.00203667,
            51.51020028
        ],
        "type": "Point"
    }
}
我试着模拟它,并用以下内容反序列化它:

public class Item
{
    [JsonProperty("geom")]
    public Geom Geom { get; set; }
}

public class Geom
{
    [JsonProperty("coordinates")]
    public double[] Coords { get; set; }

    [JsonProperty("type")]
    public string Type { get; set; }
}
并称之为:

class Program
{
    static void Main(string[] args)
    {
        new Program();
    }

    public Program()
    {
        var single = "{\"geom\":{\"coordinates\":[-0.00203667,51.51020028],\"type\":\"Point\"}}";
        var s = JsonConvert.DeserializeObject<Item>(single);

        var poly = "{\"geom\":{\"coordinates\":[[[0.07666021585464479,51.49331798632394],[0.07707864046096803,51.49337476490021],[0.07717519998550416,51.49315433003204],[0.07676750421524049,51.49309087131179],[0.07666021585464479,51.49331798632394]]],\"type\":\"Polygon\"}}";
        var p = JsonConvert.DeserializeObject<Item>(poly);
    }
}
类程序
{
静态void Main(字符串[]参数)
{
新程序();
}
公共计划()
{
var single=“{\'geom\':{\'coordinates\':[-0.00203667,51.51020028],\'type\':\'Point\'}”;
var s=JsonConvert.DeserializeObject(单个);
var poly=“{\'geom\”:{\'Coordinations\”:[[0.07666021585464479,51.49331798632394],[0.07707864046096803,51.49337476490021],[0.07717519998550416,51.49315433003204],[0.07676750421524049,51.4930908131179],[0.076660215854479,51.49331798632394],“多边形类型:”,“多边形:”;
var p=JsonConvert.DeserializeObject(poly);
}
}
我非常理解这个问题,多边形字符串需要是一个
double[][]
。但我似乎无法让相同的反序列化过程同时适用于两个字符串

如果我将它们反序列化为一个
对象
,它就会起作用,但是如果不到处强制转换,我就不能在我的具体类中使用它

我还看到一些尝试将“点”反序列化包装在try/catch中,并使用catch反序列化“多边形”,但这似乎是一种黑客行为,API中可能存在其他类型的坐标系

我正在使用Newtonsoft.Json,我已经研究了所有不同的方法,我得到的最接近的方法是拥有不同的类变量,但由于这是一个更大的资产类的子类,我不想创建一路到顶层的变量

我还研究了自定义反序列化,但我对它的理解还不足以解决这个问题


如果有人认为可以用另一个库解决这个问题,也很乐意更换serialiser。

您的数据结构如下:

公共类项目
{
[JsonProperty(“geom”)]
公共几何几何{get;set;}
}
公共抽象类Geom
{
[JsonProperty(“类型”)]
公共字符串类型{get;set;}
}
公共类多边形:Geom
{
[JsonProperty(“坐标”)]
公共双[][]坐标{get;set;}
}
公共课程点:Geom
{
[JsonProperty(“坐标”)]
公共双[]坐标{get;set;}
}
但是Json.NET无法将多态性应用于反序列化。为此,您必须创建一个自定义JsonConverter:

公共类GeomConverter:JsonConverter
{
公共覆盖布尔CanConvert(类型objectType)
{
返回typeof(Geom).IsAssignableFrom(objectType);
}
公共重写对象ReadJson(JsonReader,
类型objectType、对象existingValue、JsonSerializer序列化程序)
{
JObject=JObject.Load(读卡器);
字符串类型=作业对象[“类型”]。ToString();
Geom-Geom=null;
如果(类型==“多边形”)
{
geom=新多边形();
}
否则如果(类型=“点”)
{
geom=新点();
}
填充(jobject.CreateReader(),geom);
返回几何;
}
公共覆盖布尔可写
{
获取{return false;}
}
公共重写void WriteJson(JsonWriter编写器、对象值、JsonSerializer序列化器)
{
抛出新的NotImplementedException();
}
}
然后使用自定义JsonConverter作为反序列化对象方法的参数:

公共程序()
{
var single=“{\'geom\':{\'coordinates\':[-0.00203667,51.51020028],\'type\':\'Point\'}”;
var s=JsonConvert.DeserializeObject(单个,新的GeomConverter());
var poly=“{\'geom\”:{\'Coordinations\”:[[0.07666021585464479,51.49331798632394],[0.07707864046096803,51.49337476490021],[0.07717519998550416,51.49315433003204],[0.07676750421524049,51.4930908131179],[0.076660215854479,51.49331798632394],“多边形类型:”,“多边形:”;
var p=JsonConvert.DeserializeObject(poly,new GeomConverter());
}

非常感谢,这让我困惑了这么久。我只是想让你们知道,我已经在我的最终解决方案中实现了这种方法,而且效果非常好。
class Program
{
    static void Main(string[] args)
    {
        new Program();
    }

    public Program()
    {
        var single = "{\"geom\":{\"coordinates\":[-0.00203667,51.51020028],\"type\":\"Point\"}}";
        var s = JsonConvert.DeserializeObject<Item>(single);

        var poly = "{\"geom\":{\"coordinates\":[[[0.07666021585464479,51.49331798632394],[0.07707864046096803,51.49337476490021],[0.07717519998550416,51.49315433003204],[0.07676750421524049,51.49309087131179],[0.07666021585464479,51.49331798632394]]],\"type\":\"Polygon\"}}";
        var p = JsonConvert.DeserializeObject<Item>(poly);
    }
}