Skip to content

Commit 2e013ac

Browse files
committed
fix(jsonapi-deserializer): had method for de-serializing hasMany
requires access to the DbContext
1 parent 624d0c2 commit 2e013ac

File tree

1 file changed

+74
-22
lines changed

1 file changed

+74
-22
lines changed

src/JsonApiDotNetCore/Serialization/JsonApiDeSerializer.cs

Lines changed: 74 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -8,15 +8,19 @@
88
using JsonApiDotNetCore.Services;
99
using Newtonsoft.Json;
1010
using Newtonsoft.Json.Linq;
11+
using System.Collections;
12+
using JsonApiDotNetCore.Data;
13+
using Microsoft.EntityFrameworkCore;
1114

1215
namespace JsonApiDotNetCore.Serialization
1316
{
1417
public static class JsonApiDeSerializer
1518
{
16-
public static object Deserialize(string requestBody, IJsonApiContext context)
19+
public static object Deserialize(string requestBody, IJsonApiContext context,
20+
DbContext dbContext)
1721
{
1822
var document = JsonConvert.DeserializeObject<Document>(requestBody);
19-
var entity = DataToObject(document.Data, context);
23+
var entity = DataToObject(document.Data, context, dbContext);
2024
return entity;
2125
}
2226

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

3337

34-
public static List<TEntity> DeserializeList<TEntity>(string requestBody, IJsonApiContext context)
38+
public static List<TEntity> DeserializeList<TEntity>(string requestBody, IJsonApiContext context,
39+
DbContext dbContext)
3540
{
3641
var documents = JsonConvert.DeserializeObject<Documents>(requestBody);
3742

3843
var deserializedList = new List<TEntity>();
3944
foreach (var data in documents.Data)
4045
{
41-
var entity = DataToObject(data, context);
46+
var entity = DataToObject(data, context, dbContext);
4247
deserializedList.Add((TEntity)entity);
4348
}
4449

4550
return deserializedList;
4651
}
4752

48-
private static object DataToObject(DocumentData data, IJsonApiContext context)
53+
private static object DataToObject(DocumentData data,
54+
IJsonApiContext context,
55+
DbContext dbContext)
4956
{
5057
var entityTypeName = data.Type.ToProperCase();
5158

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

5562
var entity = Activator.CreateInstance(contextEntity.EntityType);
56-
63+
5764
entity = _setEntityAttributes(entity, contextEntity, data.Attributes);
58-
entity = _setRelationships(entity, contextEntity, data.Relationships);
65+
entity = _setRelationships(entity, contextEntity, data.Relationships, dbContext);
5966

6067
var identifiableEntity = (IIdentifiable)entity;
6168

@@ -68,6 +75,9 @@ private static object DataToObject(DocumentData data, IJsonApiContext context)
6875
private static object _setEntityAttributes(
6976
object entity, ContextEntity contextEntity, Dictionary<string, object> attributeValues)
7077
{
78+
if (attributeValues == null || attributeValues.Count == 0)
79+
return entity;
80+
7181
var entityProperties = entity.GetType().GetProperties();
7282

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

91101
private static object _setRelationships(
92-
object entity, ContextEntity contextEntity, Dictionary<string, RelationshipData> relationships)
102+
object entity,
103+
ContextEntity contextEntity,
104+
Dictionary<string, RelationshipData> relationships,
105+
DbContext context)
93106
{
94107
if (relationships == null || relationships.Count == 0)
95108
return entity;
@@ -98,29 +111,68 @@ private static object _setRelationships(
98111

99112
foreach (var attr in contextEntity.Relationships)
100113
{
101-
var entityProperty = entityProperties.FirstOrDefault(p => p.Name == $"{attr.InternalRelationshipName}Id");
114+
if (attr.IsHasOne)
115+
entity = _setHasOneRelationship(entity, entityProperties, attr, contextEntity, relationships);
116+
else
117+
entity = _setHasManyRelationship(entity, entityProperties, attr, contextEntity, relationships, context);
118+
}
102119

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

106-
var relationshipName = attr.InternalRelationshipName.Dasherize();
107-
RelationshipData relationshipData;
108-
if (relationships.TryGetValue(relationshipName, out relationshipData))
109-
{
110-
var data = (Dictionary<string, string>)relationshipData.ExposedData;
123+
private static object _setHasOneRelationship(object entity,
124+
PropertyInfo[] entityProperties,
125+
RelationshipAttribute attr,
126+
ContextEntity contextEntity,
127+
Dictionary<string, RelationshipData> relationships)
128+
{
129+
var entityProperty = entityProperties.FirstOrDefault(p => p.Name == $"{attr.InternalRelationshipName}Id");
111130

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

114-
var newValue = data["id"];
115-
var convertedValue = TypeHelper.ConvertType(newValue, entityProperty.PropertyType);
116-
entityProperty.SetValue(entity, convertedValue);
117-
}
134+
var relationshipName = attr.InternalRelationshipName.Dasherize();
135+
136+
if (relationships.TryGetValue(relationshipName, out RelationshipData relationshipData))
137+
{
138+
var data = (Dictionary<string, string>)relationshipData.ExposedData;
139+
140+
if (data == null) return entity;
141+
142+
var newValue = data["id"];
143+
var convertedValue = TypeHelper.ConvertType(newValue, entityProperty.PropertyType);
144+
entityProperty.SetValue(entity, convertedValue);
118145
}
119146

120147
return entity;
121148
}
122149

150+
private static object _setHasManyRelationship(object entity,
151+
PropertyInfo[] entityProperties,
152+
RelationshipAttribute attr,
153+
ContextEntity contextEntity,
154+
Dictionary<string, RelationshipData> relationships,
155+
DbContext context)
156+
{
157+
var entityProperty = entityProperties.FirstOrDefault(p => p.Name == attr.InternalRelationshipName);
123158

124-
159+
if (entityProperty == null)
160+
throw new JsonApiException("400", $"{contextEntity.EntityType.Name} does not contain an relationsip named {attr.InternalRelationshipName}");
161+
162+
var relationshipName = attr.InternalRelationshipName.Dasherize();
163+
164+
if (relationships.TryGetValue(relationshipName, out RelationshipData relationshipData))
165+
{
166+
var data = (List<Dictionary<string, string>>)relationshipData.ExposedData;
167+
168+
if (data == null) return entity;
169+
170+
var genericProcessor = GenericProcessorFactory.GetProcessor(attr.Type, context);
171+
var ids = relationshipData.ManyData.Select(r => r["id"]);
172+
genericProcessor.SetRelationships(entity, attr, ids);
173+
}
174+
175+
return entity;
176+
}
125177
}
126178
}

0 commit comments

Comments
 (0)