10

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

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

方法 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 对象,前提是它具有所需的属性(例如 Geometry )。缺点是我需要创建许多自定义属性来支持序列化。此外,这会产生“混淆”业务对象的影响。

最后,我还没有确定 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;

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

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

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

您是否看到为什么一种方法比另一种方法更受青睐的任何明显原因?也许还有另一种我不知道的方法?

仅供参考,我倾向于第二种方法。似乎它会更容易实现,并且整体上会更干净。我也碰巧喜欢它会创建的域对象和 GeoJson 对象之间的自然边界。

4

1 回答 1

2

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

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

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

于 2009-08-14T22:46:29.237 回答