title: Suggestions on how to create a custom GeoJson serializer using JSON.NET?
body: <p>I will be attempting to create a C# library to serialize objects to <a href="http://geojson.org/geojson-spec.html" rel="noreferrer">GeoJSON</a> using <a href="http://www.codeplex.com/Json" rel="noreferrer">Json.NET</a> ( for serialization ) and <a href="http://geoapi.codeplex.com/" rel="noreferrer">GeoAPI.NET</a> ( for geometry definitions ).  </p>
  
  <p>I have thought about two different approaches for the serialization implementation and I am not clear which one would be the best approach.  They are:</p>
  
  <p><strong>Approach 1 - Custom Attributes</strong></p>
  
  <p>The first approach involves creating several custom attributes that could be applied to any class to modify the serialization. For instance, a class might be decorated like so:</p>
  
  <pre><code>[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; }
  }
  </code></pre>
  
  <p>Serializing the object would then be as simple as:</p>
  
  <pre><code>JsonNetResult jsonNetResult = new JsonNetResult();
  jsonNetResult.Formatting = Formatting.Indented;
  jsonNetResult.Data = building;
  return jsonNetResult;
  </code></pre>
  
  <p>The advantage of this approach is that any business object could be turned into a GeoJSON object assuming it has the required properties (e.g., Geometry ).  The disadvantage would be that I would need to create a number of custom attributes to support the serialization.  Additionally, this has the affect of 'muddying' the business object.</p>
  
  <p>Finally, I have not yet determined if this approach is even possible with JSON.NET, though it seems that it will be.</p>
  
  <p><strong>Approach 2 - Custom JsonConverter</strong></p>
  
  <p>The second approach involves creating custom converters for various types. For instance I might have a GeoJsonConverter that when passed an object of a given type, say Feature, the GeoJSON object is created.  This might look like:</p>
  
  <pre><code>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);
      }
  }
  </code></pre>
  
  <p>I would then be able to serialize to GeoJson like so:</p>
  
  <pre><code>JsonNetResult jsonNetResult = new JsonNetResult();
  jsonNetResult.Formatting = Formatting.Indented;
  jsonNetResult.SerializerSettings.Converters.Add(new GeoJsonFeatureConverter());
  jsonNetResult.Data = building;
  </code></pre>
  
  <p>The advantage here is that this seems easier to create. I have proven that this approach is possible via a very simple prototype. Additionally, the <code>Feature</code> class is already defined if I link to <a href="http://code.google.com/p/nettopologysuite/" rel="noreferrer">NetTopologySuite</a>.  </p>
  
  <p>The disadvantage would be that my business objects would need to be mapped to a <code>Feature</code> before being serialized.  Though, this might be considered an advantage since this might provide a natural decoupling between the layers. There would definitely be tight coupling with the GeoAPI in both cases and NetTopologySuite in the later.  I think I am okay with that.</p>
  
  <p>I am aware of several other GeoJson serializers available such as <a href="http://viswaug.wordpress.com/2008/05/11/geojsonnet-a-net-library-to-produce-geojson-output/" rel="noreferrer">GeoJson.NET</a> however I would like an approach that is consistent with the Json.NET API as this is our serializer of choice.</p>
  
  <p>Do you see any obvious reasons why one approach would be preferred over the other?  Perhaps there is another approach that I am not aware of?</p>
  
  <p>FYI, I am leaning towards the second approach.  It seems that it would be easier to implement and that it would be cleaner overall.  I also happen to like the natural boundary between domain objects and GeoJson objects that it would create.</p>