static IResource CreateResource(JObject jObj, Type resourceType) { // remove _links and _embedded so those don't try to deserialize, because we know they will fail JToken links; if (jObj.TryGetValue(HalLinksName, out links)) { jObj.Remove(HalLinksName); } JToken embeddeds; if (jObj.TryGetValue(HalEmbeddedName, out embeddeds)) { jObj.Remove(HalEmbeddedName); } // create value properties in base object var resource = jObj.ToObject(resourceType) as IResource; if (resource == null) { return(null); } // links are named properties, where the name is Link.Rel and the value is the rest of Link if (links != null) { foreach (var rel in links.OfType <JProperty>()) { CreateLinks(rel, resource); } var self = resource.Links.SingleOrDefault(l => l.Rel == "self"); if (self != null) { resource.Href = self.Href; } } // embedded are named properties, where the name is the Rel, which needs to map to a Resource Type, and the value is the Resource // recursive if (embeddeds != null) { foreach (var prop in resourceType.GetProperties().Where(p => Representation.IsEmbeddedResourceType(p.PropertyType))) { // expects embedded collection of resources is implemented as an IList on the Representation-derived class if (typeof(IEnumerable <IResource>).IsAssignableFrom(prop.PropertyType)) { var lst = prop.GetValue(resource) as IList; if (lst == null) { lst = ConstructResource(prop.PropertyType) as IList ?? Activator.CreateInstance( typeof(List <>).MakeGenericType(prop.PropertyType.GenericTypeArguments)) as IList; if (lst == null) { continue; } prop.SetValue(resource, lst); } if (prop.PropertyType.GenericTypeArguments != null && prop.PropertyType.GenericTypeArguments.Length > 0) { CreateEmbedded(embeddeds, prop.PropertyType.GenericTypeArguments[0], newRes => lst.Add(newRes)); } } else { var prop1 = prop; CreateEmbedded(embeddeds, prop.PropertyType, newRes => prop1.SetValue(resource, newRes)); } } } return(resource); }