Skip to content

Fix/id type support #55

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 17 commits into from
Mar 15, 2017
Merged
Changes from 1 commit
Commits
Show all changes
17 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
96 changes: 74 additions & 22 deletions src/JsonApiDotNetCore/Serialization/JsonApiDeSerializer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,15 +8,19 @@
using JsonApiDotNetCore.Services;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using System.Collections;
using JsonApiDotNetCore.Data;
using Microsoft.EntityFrameworkCore;

namespace JsonApiDotNetCore.Serialization
{
public static class JsonApiDeSerializer
{
public static object Deserialize(string requestBody, IJsonApiContext context)
public static object Deserialize(string requestBody, IJsonApiContext context,
DbContext dbContext)
{
var document = JsonConvert.DeserializeObject<Document>(requestBody);
var entity = DataToObject(document.Data, context);
var entity = DataToObject(document.Data, context, dbContext);
return entity;
}

Expand All @@ -31,31 +35,34 @@ public static object DeserializeRelationship(string requestBody, IJsonApiContext
}


public static List<TEntity> DeserializeList<TEntity>(string requestBody, IJsonApiContext context)
public static List<TEntity> DeserializeList<TEntity>(string requestBody, IJsonApiContext context,
DbContext dbContext)
{
var documents = JsonConvert.DeserializeObject<Documents>(requestBody);

var deserializedList = new List<TEntity>();
foreach (var data in documents.Data)
{
var entity = DataToObject(data, context);
var entity = DataToObject(data, context, dbContext);
deserializedList.Add((TEntity)entity);
}

return deserializedList;
}

private static object DataToObject(DocumentData data, IJsonApiContext context)
private static object DataToObject(DocumentData data,
IJsonApiContext context,
DbContext dbContext)
{
var entityTypeName = data.Type.ToProperCase();

var contextEntity = context.ContextGraph.GetContextEntity(entityTypeName);
context.RequestEntity = contextEntity;

var entity = Activator.CreateInstance(contextEntity.EntityType);

entity = _setEntityAttributes(entity, contextEntity, data.Attributes);
entity = _setRelationships(entity, contextEntity, data.Relationships);
entity = _setRelationships(entity, contextEntity, data.Relationships, dbContext);

var identifiableEntity = (IIdentifiable)entity;

Expand All @@ -68,6 +75,9 @@ private static object DataToObject(DocumentData data, IJsonApiContext context)
private static object _setEntityAttributes(
object entity, ContextEntity contextEntity, Dictionary<string, object> attributeValues)
{
if (attributeValues == null || attributeValues.Count == 0)
return entity;

var entityProperties = entity.GetType().GetProperties();

foreach (var attr in contextEntity.Attributes)
Expand All @@ -89,7 +99,10 @@ private static object _setEntityAttributes(
}

private static object _setRelationships(
object entity, ContextEntity contextEntity, Dictionary<string, RelationshipData> relationships)
object entity,
ContextEntity contextEntity,
Dictionary<string, RelationshipData> relationships,
DbContext context)
{
if (relationships == null || relationships.Count == 0)
return entity;
Expand All @@ -98,29 +111,68 @@ private static object _setRelationships(

foreach (var attr in contextEntity.Relationships)
{
var entityProperty = entityProperties.FirstOrDefault(p => p.Name == $"{attr.InternalRelationshipName}Id");
if (attr.IsHasOne)
entity = _setHasOneRelationship(entity, entityProperties, attr, contextEntity, relationships);
else
entity = _setHasManyRelationship(entity, entityProperties, attr, contextEntity, relationships, context);
}

if (entityProperty == null)
throw new JsonApiException("400", $"{contextEntity.EntityType.Name} does not contain an relationsip named {attr.InternalRelationshipName}");
return entity;
}

var relationshipName = attr.InternalRelationshipName.Dasherize();
RelationshipData relationshipData;
if (relationships.TryGetValue(relationshipName, out relationshipData))
{
var data = (Dictionary<string, string>)relationshipData.ExposedData;
private static object _setHasOneRelationship(object entity,
PropertyInfo[] entityProperties,
RelationshipAttribute attr,
ContextEntity contextEntity,
Dictionary<string, RelationshipData> relationships)
{
var entityProperty = entityProperties.FirstOrDefault(p => p.Name == $"{attr.InternalRelationshipName}Id");

if (data == null) continue;
if (entityProperty == null)
throw new JsonApiException("400", $"{contextEntity.EntityType.Name} does not contain an relationsip named {attr.InternalRelationshipName}");

var newValue = data["id"];
var convertedValue = TypeHelper.ConvertType(newValue, entityProperty.PropertyType);
entityProperty.SetValue(entity, convertedValue);
}
var relationshipName = attr.InternalRelationshipName.Dasherize();

if (relationships.TryGetValue(relationshipName, out RelationshipData relationshipData))
{
var data = (Dictionary<string, string>)relationshipData.ExposedData;

if (data == null) return entity;

var newValue = data["id"];
var convertedValue = TypeHelper.ConvertType(newValue, entityProperty.PropertyType);
entityProperty.SetValue(entity, convertedValue);
}

return entity;
}

private static object _setHasManyRelationship(object entity,
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Closes #52

PropertyInfo[] entityProperties,
RelationshipAttribute attr,
ContextEntity contextEntity,
Dictionary<string, RelationshipData> relationships,
DbContext context)
{
var entityProperty = entityProperties.FirstOrDefault(p => p.Name == attr.InternalRelationshipName);


if (entityProperty == null)
throw new JsonApiException("400", $"{contextEntity.EntityType.Name} does not contain an relationsip named {attr.InternalRelationshipName}");

var relationshipName = attr.InternalRelationshipName.Dasherize();

if (relationships.TryGetValue(relationshipName, out RelationshipData relationshipData))
{
var data = (List<Dictionary<string, string>>)relationshipData.ExposedData;

if (data == null) return entity;

var genericProcessor = GenericProcessorFactory.GetProcessor(attr.Type, context);
var ids = relationshipData.ManyData.Select(r => r["id"]);
genericProcessor.SetRelationships(entity, attr, ids);
}

return entity;
}
}
}