8
8
using JsonApiDotNetCore . Services ;
9
9
using Newtonsoft . Json ;
10
10
using Newtonsoft . Json . Linq ;
11
+ using System . Collections ;
12
+ using JsonApiDotNetCore . Data ;
13
+ using Microsoft . EntityFrameworkCore ;
11
14
12
15
namespace JsonApiDotNetCore . Serialization
13
16
{
14
17
public static class JsonApiDeSerializer
15
18
{
16
- public static object Deserialize ( string requestBody , IJsonApiContext context )
19
+ public static object Deserialize ( string requestBody , IJsonApiContext context ,
20
+ DbContext dbContext )
17
21
{
18
22
var document = JsonConvert . DeserializeObject < Document > ( requestBody ) ;
19
- var entity = DataToObject ( document . Data , context ) ;
23
+ var entity = DataToObject ( document . Data , context , dbContext ) ;
20
24
return entity ;
21
25
}
22
26
@@ -31,31 +35,34 @@ public static object DeserializeRelationship(string requestBody, IJsonApiContext
31
35
}
32
36
33
37
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 )
35
40
{
36
41
var documents = JsonConvert . DeserializeObject < Documents > ( requestBody ) ;
37
42
38
43
var deserializedList = new List < TEntity > ( ) ;
39
44
foreach ( var data in documents . Data )
40
45
{
41
- var entity = DataToObject ( data , context ) ;
46
+ var entity = DataToObject ( data , context , dbContext ) ;
42
47
deserializedList . Add ( ( TEntity ) entity ) ;
43
48
}
44
49
45
50
return deserializedList ;
46
51
}
47
52
48
- private static object DataToObject ( DocumentData data , IJsonApiContext context )
53
+ private static object DataToObject ( DocumentData data ,
54
+ IJsonApiContext context ,
55
+ DbContext dbContext )
49
56
{
50
57
var entityTypeName = data . Type . ToProperCase ( ) ;
51
58
52
59
var contextEntity = context . ContextGraph . GetContextEntity ( entityTypeName ) ;
53
60
context . RequestEntity = contextEntity ;
54
61
55
62
var entity = Activator . CreateInstance ( contextEntity . EntityType ) ;
56
-
63
+
57
64
entity = _setEntityAttributes ( entity , contextEntity , data . Attributes ) ;
58
- entity = _setRelationships ( entity , contextEntity , data . Relationships ) ;
65
+ entity = _setRelationships ( entity , contextEntity , data . Relationships , dbContext ) ;
59
66
60
67
var identifiableEntity = ( IIdentifiable ) entity ;
61
68
@@ -68,6 +75,9 @@ private static object DataToObject(DocumentData data, IJsonApiContext context)
68
75
private static object _setEntityAttributes (
69
76
object entity , ContextEntity contextEntity , Dictionary < string , object > attributeValues )
70
77
{
78
+ if ( attributeValues == null || attributeValues . Count == 0 )
79
+ return entity ;
80
+
71
81
var entityProperties = entity . GetType ( ) . GetProperties ( ) ;
72
82
73
83
foreach ( var attr in contextEntity . Attributes )
@@ -89,7 +99,10 @@ private static object _setEntityAttributes(
89
99
}
90
100
91
101
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 )
93
106
{
94
107
if ( relationships == null || relationships . Count == 0 )
95
108
return entity ;
@@ -98,29 +111,68 @@ private static object _setRelationships(
98
111
99
112
foreach ( var attr in contextEntity . Relationships )
100
113
{
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
+ }
102
119
103
- if ( entityProperty == null )
104
- throw new JsonApiException ( "400" , $ " { contextEntity . EntityType . Name } does not contain an relationsip named { attr . InternalRelationshipName } " ) ;
120
+ return entity ;
121
+ }
105
122
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") ;
111
130
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 } ") ;
113
133
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 ) ;
118
145
}
119
146
120
147
return entity ;
121
148
}
122
149
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 ) ;
123
158
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
+ }
125
177
}
126
178
}
0 commit comments