Я буду пытаться создать библиотеку С# для сериализации объектов 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, предполагая, что он обладает требуемыми свойствами (например, 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;
Преимущество в том, что это кажется более простым в создании. Я доказал, что этот подход возможен через очень простой прототип. Кроме того, класс Feature
уже определен, если я ссылаюсь на NetTopologySuite.
Недостатком было бы то, что мои бизнес-объекты должны были быть сопоставлены с Feature
перед сериализацией. Хотя это можно считать преимуществом, поскольку это может обеспечить естественную развязку между слоями. В обоих случаях определенно будет тесная связь с GeoAPI в обоих случаях и NetTopologySuite в дальнейшем. Думаю, я в порядке.
Мне известно о нескольких других сериализаторах GeoJson, таких как GeoJson.NET, однако мне нужен подход, который согласуется с Json.NET API, так как это наш сериализатор выбора.
Вы видите очевидные причины, по которым один подход был бы предпочтительнее другого? Возможно, есть другой подход, о котором я не знаю?
FYI, я склоняюсь к второму подходу. Похоже, что было бы проще реализовать и что оно будет более чистым в целом. Мне также нравится естественная граница между объектами домена и объектами GeoJson, которые он создавал.