private JToken SerializeData(SerializationContext serializationContext, IDictionary<string, JToken> properties) { var data = SerializeMinimalData(serializationContext, properties); var attributes = SerializeAttributes(serializationContext, properties); if (attributes != null) { data["attributes"] = attributes; } var relationships = SerializeRelationships(serializationContext, properties); if (relationships != null) { data["relationships"] = relationships; } if (serializationContext.IsCollection) { data["links"] = AddUrl( serializationContext.BaseUrl, new JObject(), "self", _urlBuilder.BuildCanonicalPath(serializationContext.Resource, EnsureHasId(properties, serializationContext.Resource).Value<string>())); } return data; }
private JObject BuildJsonResult(ResourceResult resourceResult, string requestUri) { var serializationContext = new SerializationContext { Object = resourceResult.Result, Resource = resourceResult.Resource, IncludedSections = new JArray(), BaseUrl = requestUri, QueryContext = resourceResult.QueryContext }; if (serializationContext.Object == null) { return SerializeNull(serializationContext); } var objectJson = JToken.FromObject(serializationContext.Object, _serializer); serializationContext.IsCollection = objectJson is JArray; var result = new JObject { ["data"] = SerializeArrayOrObject(serializationContext, objectJson, SerializeData), ["links"] = new JObject { ["self"] = new JValue(serializationContext.BaseUrl) } ["links"] = CreateTopLevelLinks(serializationContext, serializationContext.IsCollection ? objectJson.Count() : 0) }; if (serializationContext.IncludedSections.Count > 0) { result["included"] = serializationContext.IncludedSections; } return result; }
private JToken CreateTopLevelLinks(SerializationContext serializationContext, int itemCount = 0) { var result = new JObject { ["self"] = serializationContext.BaseUrl }; if (serializationContext.QueryContext?.Pagination != null) { var queryStrings = new PaginationQuery(serializationContext.QueryContext.Pagination); var left = new Uri(serializationContext.BaseUrl).GetComponents(UriComponents.SchemeAndServer | UriComponents.Path, UriFormat.Unescaped); if (queryStrings.FirstPage != null) { result["first"] = new Uri(left + queryStrings.FirstPage); } if (queryStrings.NextPage != null && itemCount >= serializationContext.QueryContext.Pagination.PerPage) { result["next"] = new Uri(left + queryStrings.NextPage); } if (queryStrings.PreviousPage != null) { result["prev"] = new Uri(left + queryStrings.PreviousPage); } } return result; }
private static JToken SerializeArrayOrObject(SerializationContext serializationContext, JToken token, Func<SerializationContext, IDictionary<string, JToken>, JToken> serializeObj) { var dataArray = token as JArray; // single thing, just serialize it if (dataArray == null) { return token is JObject ? serializeObj(serializationContext, (JObject)token) : null; } // serialize each element separately var data = new JArray(); foreach (var obj in dataArray.OfType<JObject>()) { data.Add(serializeObj(serializationContext, obj)); } return data; }
private JObject SerializeNull(SerializationContext serializationContext) { return new JObject { ["data"] = null, ["links"] = CreateTopLevelLinks(serializationContext) }; }
private JToken SerializeMinimalData(SerializationContext serializationContext, IDictionary<string, JToken> properties) { return SerializeMinimalData(serializationContext, properties, serializationContext.Resource); }
private JToken SerializeMinimalData(SerializationContext serializationContext, IDictionary<string, JToken> properties, ApiResource resource) { var data = new JObject { ["type"] = resource.ResourceType.ToDashed(), ["id"] = EnsureHasId(properties, resource) }; return data; }
private static JToken SerializeAttributes(SerializationContext serializationContext, IDictionary<string, JToken> properties) { return SerializeAttributes(serializationContext, properties, serializationContext.Resource); }
private static JToken SerializeAttributes(SerializationContext serializationContext, IDictionary<string, JToken> properties, ApiResource resource) { var attributes = new JObject(); foreach (var attr in resource.Attributes) { var value = GetValue(attr.Name, properties); if (value != null) { attributes.Add(attr.Name, value); } } return attributes; }
private JToken GetMinimumRelationship(SerializationContext serializationContext, string id, ResourceRelationship relationship, string relationshipId) { var links = new JObject(); AddUrl(serializationContext.BaseUrl, links, "self", _urlBuilder.BuildRelationshipPath(serializationContext.Resource, id, relationship)); AddUrl(serializationContext.BaseUrl, links, "related", _urlBuilder.BuildRelationshipPath(serializationContext.Resource, id, relationship, relationshipId)); return new JObject { ["links"] = links }; }
private bool IsResourceIncluded(SerializationContext context, JToken includedData) { return context.IncludedSections.Any(t => t.Value<string>("type") == includedData.Value<string>("type") && t.Value<string>("id") == includedData.Value<string>("id")); }
private JToken GetRelationshipData(SerializationContext serializationContext, ResourceRelationship relationship, JToken relationshipValues) { var data = SerializeArrayOrObject( serializationContext, relationshipValues, (context, props) => { var values = SerializeMinimalData(context, props, relationship.RelatedResource); var includedData = values.DeepClone(); var url = _urlBuilder.BuildCanonicalPath( relationship.RelatedResource, EnsureHasId(props, relationship.RelatedResource).Value<string>()); includedData["attributes"] = SerializeAttributes(context, props, relationship.RelatedResource); includedData["links"] = AddUrl(context.BaseUrl, new JObject(), "self", url); if (!IsResourceIncluded(context, includedData)) { context.IncludedSections.Add(includedData); } return values; }); return data; }
private JToken SerializeRelationship(SerializationContext serializationContext, ResourceRelationship relationship, IDictionary<string, JToken> properties) { var relationshipValues = GetValue(relationship.Name, properties); var relationshipProperties = relationshipValues as JObject; // serialize the links part (so the data can be fetched) var objId = EnsureHasId(properties, serializationContext.Resource); var relToken = GetMinimumRelationship( serializationContext, objId.ToString(), relationship, relationshipProperties != null ? GetId(relationshipProperties, relationship.RelatedResource).Value<string>() : null); if (relationshipValues == null) { return relToken; } // only include data if it exists, otherwise just assume it should be fetched later var data = GetRelationshipData(serializationContext, relationship, relationshipValues); if (data != null) { relToken["data"] = data; } return relToken; }
private JToken SerializeRelationships(SerializationContext serializationContext, IDictionary<string, JToken> properties) { var relationships = new JObject(); foreach (var rel in serializationContext.Resource.Relationships) { relationships[rel.Name] = SerializeRelationship(serializationContext, rel, properties); } return relationships; }