88using JsonApiDotNetCore . Services ;
99using Newtonsoft . Json ;
1010using Newtonsoft . Json . Linq ;
11+ using System . Collections ;
12+ using JsonApiDotNetCore . Data ;
13+ using Microsoft . EntityFrameworkCore ;
1114
1215namespace 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