Created
December 15, 2014 18:12
-
-
Save nsantorello/1a8a45d75a4df6980dfb to your computer and use it in GitHub Desktop.
JsonConverter for easily deserializing Contentful API responses with JSON.NET
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using Newtonsoft.Json; | |
using System.Collections.Generic; | |
using Newtonsoft.Json.Linq; | |
using System.Text; | |
namespace Grounded | |
{ | |
public class ContentfulLinkConverter : JsonConverter | |
{ | |
private Dictionary<string, JObject> _includes; | |
private Type _excludedType; | |
// This flag makes it so that the first call to CanConvert that passes the excluded type will return false. | |
// Rather than excluding the type, we'll have to just fail the very first call | |
// since it will be the type we are trying to convert. If we exclude the type | |
// we're deserializing, then we won't be able to deserialize references it has | |
// to its own type. | |
private bool _canConvertFlag = false; | |
public ContentfulLinkConverter (Dictionary<string, JObject> includes, Type excludedType) | |
{ | |
_includes = includes; | |
_excludedType = excludedType; | |
} | |
#region implemented abstract members of JsonConverter | |
public override void WriteJson (JsonWriter writer, object value, JsonSerializer serializer) | |
{ | |
throw new NotImplementedException (); | |
} | |
public override object ReadJson (JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) | |
{ | |
var json = JObject.Load (reader); | |
var id = json ["sys"] ["id"].ToString (); | |
var linkType = json ["sys"] ["linkType"].ToString (); | |
if (!_includes.ContainsKey (id)) { | |
throw new JsonException ("The object with the ID '" + id + "' was not included in the JSON response."); | |
} | |
return JsonConvert.DeserializeObject ( | |
linkType == "Asset" ? _includes[id]["fields"]["file"].ToString() : _includes [id] ["fields"].ToString(), | |
objectType, | |
new ContentfulLinkConverter(_includes, objectType)); | |
} | |
public override bool CanConvert (Type objectType) | |
{ | |
var isExcluded = objectType.Equals (_excludedType); | |
var canConvert = (_canConvertFlag || !isExcluded) && objectType.Namespace == this.GetType ().Namespace; | |
if (isExcluded) { | |
_canConvertFlag = true; | |
} | |
return canConvert; | |
} | |
#endregion | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// This assumes you know the type of the objects in the response, and they are all | |
// the same Contentful type. If not, minor modifications will be necessary. | |
private void ContentfulSuccess(string resp) | |
{ | |
JObject json = JObject.Parse (resp); | |
if (json == null || json["items"] == null) | |
return; | |
// Create mapping of included files by ID to prevent an n^2 operation. | |
var includes = new Dictionary<string, JObject> (); | |
var jsonIncludes = json ["includes"] ["Entry"].Concat (json ["includes"] ["Asset"]); | |
foreach (JObject include in jsonIncludes) { | |
includes [include ["sys"] ["id"].ToString()] = include; | |
} | |
// MyType = some type that maps JSON properties to C# properties with the JsonPropertyAttribute | |
var deserializedObjects = new List<MyType> (); | |
foreach (JObject obj in json["items"]) { | |
deserializedObjects.Add(JsonConvert.DeserializeObject<MyType> ( | |
obj ["fields"].ToString(), new ContentfulLinkConverter(includes, typeof(MyType)))); | |
} | |
// Do something with deserializedObjects list! | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment