2009-08-11 4 views
10

Je vais essayer de créer une bibliothèque C# pour sérialiser les objets à GeoJSON en utilisant Json.NET (pour la sérialisation) et GeoAPI.NET (pour les définitions de géométrie).Suggestions pour créer un sérialiseur GeoJson personnalisé à l'aide de JSON.NET?

J'ai réfléchi à deux approches différentes pour la mise en œuvre de la sérialisation et je ne suis pas sûr lequel serait la meilleure approche. Ils sont:

Approche 1 - Attributs personnalisés

La première approche consiste à créer plusieurs attributs personnalisés qui pourraient être appliquées à toute catégorie de modifier la sérialisation. Par exemple, une classe peut être décorée comme ceci:

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

sérialisation l'objet serait alors aussi simple que:

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

L'avantage de cette approche est que tout objet métier pourrait être transformé en un Objet GeoJSON en supposant qu'il a les propriétés requises (par exemple, géométrie). L'inconvénient serait que je devrais créer un certain nombre d'attributs personnalisés pour prendre en charge la sérialisation. En outre, cela a pour effet de "brouiller" l'objet métier.

Enfin, je n'ai pas encore déterminé si cette approche est même possible avec JSON.NET, bien qu'il semble que ce sera le cas.

Approche 2 - Personnalisé JsonConverter

La deuxième approche consiste à créer des convertisseurs personnalisés pour différents types. Par exemple, je pourrais avoir un GeoJsonConverter qui quand passé un objet d'un type donné, disons Feature, l'objet GeoJSON est créé. Cela pourrait ressembler à:

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

Je serais alors en mesure de sérialisation à GeoJSON comme ceci:

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

L'avantage est que cela semble plus facile de créer. J'ai prouvé que cette approche est possible via un prototype très simple. De plus, la classe Feature est déjà définie si je lie à NetTopologySuite.

L'inconvénient serait que mes objets métier doivent être mappés à un Feature avant d'être sérialisés. Cependant, cela pourrait être considéré comme un avantage, car cela pourrait fournir un découplage naturel entre les couches. Il y aurait certainement un couplage étroit avec le GeoAPI dans les deux cas et NetTopologySuite dans le dernier. Je pense que je vais bien avec ça.

Je suis conscient de plusieurs autres sérialiseurs GeoJson disponibles tels que GeoJson.NET mais je voudrais une approche qui soit cohérente avec l'API Json.NET car c'est notre sérialiseur de choix.

Voyez-vous des raisons évidentes pour lesquelles une approche serait préférée à l'autre? Peut-être qu'il y a une autre approche que je ne connais pas?

FYI, je penche vers la deuxième approche. Il semble que ce serait plus facile à mettre en œuvre et qu'il serait plus propre dans l'ensemble. Il m'arrive aussi d'aimer la frontière naturelle entre les objets de domaine et les objets GeoJson qu'il créerait.

Répondre

2

Personnellement, je pencherais vers le premier choix, pour une raison simple. Si vous observez le framework .NET, il existe un analogue à votre sérialisation dans l'espace de noms System.Xml.Serialization. Là, ils font presque exactement ce que vous suggérez dans votre première approche.

Cependant, si vous n'aimez pas particulièrement cela, je suggérerais une troisième approche: écrire un formateur de sérialisation personnalisé, en implémentant System.Runtime.Serialization.IFormatter. Cela vous donne la possibilité d'utiliser la notation de sérialisation standard et les mécanismes pour vos objets (comme [Serializable] et ISerializable), mais vous suivez un modèle bien reconnu, rendant l'utilisation facile à reconnaître. De plus comme un bonus supplémentaire, vous pouvez facilement soutenir d'autres formes de sérialisation (binaire, du savon, d'autres formats personnalisés) sur la route en échangeant votre mise en œuvre de IFormatter

Edit: voici un exemple: http://geekswithblogs.net/luskan/archive/2007/07/16/113956.aspx

Questions connexes