且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

JSON.NET - 条件类型反序列化

更新时间:2022-01-08 08:00:14

我把一个样品转换器,你指出正确的方向。下面是我的示例JSON字符串:

I put together a sample converter to point you in the right direction. Here are my sample JSON strings:

{geometryType:esriGeometryPolygon几何:{环:5}}

{geometryType: "esriGeometryPolygon", geometry: { rings: 5 } }

{geometryType:esriGeometryOther几何:{环:5}}

{geometryType: "esriGeometryOther", geometry: { rings: 5 } }

我测试了它像这样的:

var serializer = new JsonSerializer();
var geometry = serializer.Deserialize<Geometry>(new JsonTextReader(new StringReader(jsonData)));

//Should have correctly typed instance here...



在这里是转换器和样品几何对象:

And here is the converter and sample geometry objects:

public class GeometryConverter : JsonConverter
{
    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
    {
        throw new NotImplementedException();
    }

    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
    {
        if (reader.TokenType == JsonToken.Null)
            return null;

        reader.Read(); // startobject

        //we should be at geometry type property now
        if ((string)reader.Value != "geometryType") throw new InvalidOperationException();

        reader.Read(); //propertyName

        var type = (string)reader.Value;

        Geometry value;

        switch(type)
        {
            case "esriGeometryPolygon":
                value = new PolygonGeometry();
                break;
            case "esriGeometryOther":
                value = new OtherGeometry();
                break;
            default:
                throw new NotSupportedException();
        }

        reader.Read(); // move to inner object property
        //should probably confirm name here

        reader.Read(); //move to inner object

        serializer.Populate(reader, value);

        reader.Read(); //move outside container (should be end object)

        return value;
    }

    public override bool CanConvert(Type objectType)
    {
        return typeof(Geometry).IsAssignableFrom(objectType);
    }
}

[JsonConverter(typeof(GeometryConverter))]
public class OtherGeometry : Geometry
{

}

[JsonConverter(typeof(GeometryConverter))]
public class PolygonGeometry : Geometry
{

}

[JsonConverter(typeof(GeometryConverter))]
public class Geometry
{
    public int rings { get; set; }
}