我将尝试创建一个 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 对象之间的自然边界。