2009-08-11 40 views
10

Intentaré crear una biblioteca de C# para serializar objetos a GeoJSON utilizando Json.NET (para serialización) y GeoAPI.NET (para las definiciones de geometría).Sugerencias sobre cómo crear un serializador GeoJson personalizado usando JSON.NET?

He pensado en dos enfoques diferentes para la implementación de la serialización y no estoy seguro de cuál sería el mejor enfoque. Ellos son:

Enfoque 1 - Atributos personalizados

El primer enfoque implica la creación de varios atributos personalizados que podrían ser aplicadas a cualquier clase de modificar la serialización. Por ejemplo, una clase puede ser decorado de este modo:

[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; } 
} 

de números de serie del objeto sería entonces tan simple como:

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

La ventaja de este enfoque es que cualquier objeto de negocio se podría convertir en una Objeto GeoJSON suponiendo que tiene las propiedades requeridas (p. Ej., Geometría). La desventaja sería que tendría que crear una serie de atributos personalizados para admitir la serialización. Además, esto tiene el efecto de 'enlodar' el objeto comercial.

Finalmente, aún no he determinado si este enfoque es posible con JSON.NET, aunque parece que sí lo será.

Enfoque 2 - Custom JsonConverter

El segundo enfoque implica la creación de convertidores personalizados para diversos tipos. Por ejemplo, podría tener un GeoJsonConverter que cuando pasa un objeto de un tipo determinado, como Feature, se crea el objeto GeoJSON. Esto podría ser:

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); 
    } 
} 

Me entonces será capaz de serializar a GeoJSON así:

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

La ventaja aquí es que esto parece más fácil de crear. He demostrado que este enfoque es posible a través de un prototipo muy simple. Además, la clase Feature ya está definida si conecto con NetTopologySuite.

La desventaja sería que mis objetos comerciales tendrían que mapearse en un Feature antes de ser serializados. Sin embargo, esto podría considerarse una ventaja ya que esto podría proporcionar un desacoplamiento natural entre las capas. Definitivamente habría un estrecho acoplamiento con GeoAPI en ambos casos y con NetTopologySuite en el futuro. Creo que estoy de acuerdo con eso.

Conozco otros serializadores de GeoJson disponibles, como GeoJson.NET; sin embargo, me gustaría un enfoque que sea coherente con la API de Json.NET ya que este es nuestro serializador de elección.

¿Ve alguna razón obvia de por qué un enfoque sería preferible al otro? Quizás hay otro enfoque del que no estoy enterado?

FYI, me estoy inclinando hacia el segundo enfoque. Parece que sería más fácil de implementar y que sería más limpio en general. También me gusta el límite natural entre los objetos de dominio y los objetos de GeoJson que crearía.

Respuesta

2

Personalmente me inclino hacia la primera opción, por una razón simple. Si observa el framework .NET, hay un análogo a su serialización en el espacio de nombres System.Xml.Serialization. Allí hacen casi exactamente lo que estás sugiriendo en tu primer acercamiento.

Sin embargo, si no te gusta particularmente, sugeriría un tercer enfoque: escribir un formateador de serialización personalizado, implementando System.Runtime.Serialization.IFormatter. Esto le da la capacidad de utilizar la notación de serialización estándar y los mecanismos para sus objetos (como [Serializable] y ISerializable), pero está siguiendo un patrón bien reconocido, por lo que su uso es fácil de reconocer. Además como ventaja adicional que puede soportar fácilmente otras formas de serialización (binario, jabón, otros formatos personalizados) en el camino mediante el canje de su aplicación IFormatter

Editar: he aquí un ejemplo: http://geekswithblogs.net/luskan/archive/2007/07/16/113956.aspx

Cuestiones relacionadas