关于如何使用JSON.NET创建自定义GeoJson序列化程序的建议?

时间:2009-08-11 19:21:06

标签: c# json.net geojson

我将尝试创建一个C#库,使用GeoJSON(用于序列化)和Json.NET(用于几何定义)将对象序列化为GeoAPI.NET

我已经考虑过两种不同的序列化实现方法,我不清楚哪种方法是最好的方法。他们是:

方法1 - 自定义属性

第一种方法涉及创建几个可应用于任何类的自定义属性来修改序列化。例如,一个类可能会这样装饰:

[GeoJsonFeature]
public class Building
{
   [GeoJsonId]
   public Guid Id { get; set; }
   [GeoJsonProperty]
   public string Name { get; set; }
   [GeoJsonProperty]
   public int Floorcount { get; set; }
   [GeoJsonGeometry]
   public GeoAPI.Geometries.IGeometry Geometry { get; set; }
}

序列化对象将非常简单:

JsonNetResult jsonNetResult = new JsonNetResult();
jsonNetResult.Formatting = Formatting.Indented;
jsonNetResult.Data = building;
return jsonNetResult;

这种方法的优点是,任何业务对象都可以转换为GeoJSON对象,假设它具有所需的属性(例如,几何)。缺点是我需要创建一些自定义属性来支持序列化。此外,这会影响业务对象的“混乱”。

最后,我还没有确定JSON.NET是否可以实现这种方法,尽管它似乎是可以的。

方法2 - 自定义JsonConverter

第二种方法涉及为各种类型创建自定义转换器。例如,我可能有一个GeoJsonConverter,当传递给定类型的对象,比如Feature时,会创建GeoJSON对象。这可能看起来像:

public class GeoJsonFeatureConverter
{
    public override void WriteJson(JsonWriter writer, object value, JsonSerializer)
    {  
        // serializing code here 
    }

    public override void ReadJson(JsonReader reader, Type objectType, JsonSerializer serializer)
    {  
        // deserializing code here 
    }

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

然后我可以像这样序列化到GeoJson:

JsonNetResult jsonNetResult = new JsonNetResult();
jsonNetResult.Formatting = Formatting.Indented;
jsonNetResult.SerializerSettings.Converters.Add(new GeoJsonFeatureConverter());
jsonNetResult.Data = building;

这里的优点是这似乎更容易创建。我已经证明这种方法可以通过一个非常简单的原型实现。此外,如果我链接到NetTopologySuite,则已定义Feature类。

缺点是我的业务对象需要在序列化之前映射到Feature。虽然,这可能被认为是一个优点,因为这可能提供层之间的自然解耦。在两种情况下肯定会与GeoAPI紧密耦合,而在后来的情况下与NetTopologySuite紧密耦合。我想我没关系。

我知道其他几个可用的GeoJson序列化程序,例如GeoJson.NET但是我想要一种与Json.NET API一致的方法,因为这是我们选择的序列化程序。

你是否看到任何明显的理由为什么一种方法优先于另一种?也许还有另一种我不知道的方法?

仅供参考,我倾向于采用第二种方法。它似乎更容易实施,而且总体来说更清洁。我也碰巧喜欢它会创建的域对象和GeoJson对象之间的自然边界。

1 个答案:

答案 0 :(得分:2)

我个人倾向于第一选择,原因很简单。如果查看.NET框架,可以在System.Xml.Serialization命名空间中对序列化进行类比。在那里,他们几乎完全按照你在第一种方法中提出的建议。

但是,如果您不特别喜欢,我建议采用第三种方法:编写自定义序列化格式化程序,实现System.Runtime.Serialization.IFormatter。这使您能够为对象使用标准序列化表示法和机制(如[Serializable]和ISerializable),但您遵循一个公认的模式,使用易于识别。此外,通过更换IFormatter实现,您可以轻松支持其他形式的序列化(二进制,肥皂,其他自定义格式)

编辑:这是一个例子:http://geekswithblogs.net/luskan/archive/2007/07/16/113956.aspx