2009-08-11 18 views
10

Si tenterà di creare una libreria C# per serializzare gli oggetti su GeoJSON utilizzando Json.NET (per la serializzazione) e GeoAPI.NET (per le definizioni di geometria).Suggerimenti su come creare un serializzatore GeoJson personalizzato usando JSON.NET?

Ho pensato a due diversi approcci per l'implementazione della serializzazione e non sono chiaro quale sarebbe l'approccio migliore. Essi sono:

Approccio 1 - Attributi personalizzati

Il primo approccio prevede la creazione di diversi attributi personalizzati che potrebbero essere applicati a qualsiasi classe di modificare la serializzazione. Per esempio, una classe potrebbe essere decorato in questo 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; } 
} 

serializzazione l'oggetto sarebbe quindi essere semplice come:

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

Il vantaggio di questo approccio è che ogni oggetto di business potrebbe essere trasformata in un Oggetto GeoJSON assumendo che abbia le proprietà richieste (ad es. Geometria). Lo svantaggio sarebbe che avrei bisogno di creare un numero di attributi personalizzati per supportare la serializzazione. Inoltre, questo ha l'effetto di "confondere" l'oggetto aziendale.

Infine, non ho ancora determinato se questo approccio è addirittura possibile con JSON.NET, anche se sembra che lo sarà.

Approccio 2 - Custom JsonConverter

Il secondo approccio consiste nel creare convertitori personalizzati per i vari tipi. Ad esempio, potrei avere un GeoJsonConverter che quando viene passato un oggetto di un determinato tipo, ad esempio Feature, viene creato l'oggetto GeoJSON. Questo potrebbe sembrare:

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

Vorrei quindi essere in grado di serializzare a GeoJSON in questo modo:

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

Il vantaggio è che questo sembra più facile da creare. Ho dimostrato che questo approccio è possibile tramite un prototipo molto semplice. Inoltre, la classe Feature è già definita se collego a NetTopologySuite.

Lo svantaggio sarebbe che i miei oggetti aziendali avrebbero bisogno di essere mappati su un Feature prima di essere serializzati. Tuttavia, questo potrebbe essere considerato un vantaggio poiché ciò potrebbe fornire un naturale disaccoppiamento tra gli strati. Ci sarebbe sicuramente un accoppiamento stretto con GeoAPI in entrambi i casi e NetTopologySuite nella successiva. Penso di essere d'accordo con quello.

Sono a conoscenza di molti altri serializzatori GeoJson disponibili come GeoJson.NET tuttavia vorrei un approccio coerente con l'API Json.NET poiché questo è il nostro serializzatore di scelta.

Vedi qualche ovvio motivo per cui un approccio sarebbe preferito rispetto all'altro? Forse c'è un altro approccio di cui non sono a conoscenza?

FYI, mi sto appoggiando al secondo approccio. Sembra che sarebbe più facile da implementare e che sarebbe più pulito nel complesso. Mi piace anche il confine naturale tra oggetti di dominio e oggetti GeoJson che creerebbe.

risposta

2

Personalmente mi sporgo verso la prima scelta, per una semplice ragione. Se si osserva il framework .NET, esiste un analogo alla serializzazione nello spazio dei nomi System.Xml.Serialization. Lì fanno quasi esattamente quello che stai suggerendo nel tuo primo approccio.

Tuttavia, se non vi piace particolarmente, suggerirei un terzo approccio: scrivere un formattatore di serializzazione personalizzato, implementando System.Runtime.Serialization.IFormatter. Questo ti dà la possibilità di usare notazioni e meccanismi di serializzazione standard per i tuoi oggetti (come [Serializable] e ISerializable), ma stai seguendo un modello ben riconosciuto, rendendolo facile da riconoscere. Plus come un ulteriore bonus si può facilmente sostenere altre forme di serializzazione (binaria, sapone, altri formati personalizzati) lungo la strada scambiando la vostra implementazione IFormatter

Edit: ecco un esempio: http://geekswithblogs.net/luskan/archive/2007/07/16/113956.aspx

Problemi correlati