private void ParseObject(NodeContext nodeContext, EntityAspect targetAspect) { // backingStore will be null if not allowed to overwrite the entity. var backingStore = (targetAspect == null) ? null : targetAspect.BackingStore; var dict = (IDictionary <String, JToken>)nodeContext.Node; var structuralType = nodeContext.StructuralType; // needs to be the current namingConvention var nc = _mappingContext.EntityManager.MetadataStore.NamingConvention; dict.ForEach(kvp => { var key = nc.ServerPropertyNameToClient(kvp.Key, structuralType); var prop = structuralType.GetProperty(key); if (prop != null) { if (prop.IsDataProperty) { if (backingStore != null) { var dp = (DataProperty)prop; if (dp.IsComplexProperty) { var newCo = (IComplexObject)kvp.Value.ToObject(dp.ClrType); var co = (IComplexObject)backingStore[key]; var coBacking = co.ComplexAspect.BackingStore; newCo.ComplexAspect.BackingStore.ForEach(kvp2 => { coBacking[kvp2.Key] = kvp2.Value; }); } else { var val = kvp.Value; if (val.Type == JTokenType.Null && dp.ClrType != typeof(String) && !TypeFns.IsNullableType(dp.ClrType)) { // this can only happen if the client is nonnullable but the server is nullable. backingStore[key] = dp.DefaultValue; } else if (dp.IsEnumType || (dp.DataType.ClrType == typeof(TimeSpan))) { backingStore[key] = val.ToObject(dp.ClrType, _customSerializer); } else { backingStore[key] = val.ToObject(dp.ClrType); } } } } else { // prop is a ComplexObject var np = (NavigationProperty)prop; if (kvp.Value.HasValues) { NodeContext newContext; if (np.IsScalar) { var nestedOb = (JObject)kvp.Value; newContext = new NodeContext() { Node = nestedOb, ObjectType = prop.ClrType, StructuralProperty = np }; var entity = (IEntity)CreateAndPopulate(newContext); if (backingStore != null) { backingStore[key] = entity; } } else { var nestedArray = (JArray)kvp.Value; var navSet = (INavigationSet)TypeFns.CreateGenericInstance(typeof(NavigationSet <>), prop.ClrType); nestedArray.Cast <JObject>().ForEach(jo => { newContext = new NodeContext() { Node = jo, ObjectType = prop.ClrType, StructuralProperty = np }; var entity = (IEntity)CreateAndPopulate(newContext); navSet.Add(entity); }); // add to existing nav set if there is one otherwise just set it. object tmp; if (backingStore.TryGetValue(key, out tmp)) { var backingNavSet = (INavigationSet)tmp; navSet.Cast <IEntity>().ForEach(e => backingNavSet.Add(e)); } else { navSet.NavigationProperty = np; navSet.ParentEntity = targetAspect.Entity; backingStore[key] = navSet; } } } else { // do nothing //if (!np.IsScalar) { // return TypeFns.ConstructGenericInstance(typeof(NavigationSet<>), prop.ClrType); //} else { // return null; //} } } } else { if (backingStore != null) { backingStore[key] = kvp.Value.ToObject <Object>(); } } }); }
private void ParseObject(JsonContext jsonContext, EntityAspect targetAspect) { // backingStore will be null if not allowed to overwrite the entity. var backingStore = (targetAspect == null) ? null : targetAspect.BackingStore; var dict = (IDictionary <String, JToken>)jsonContext.JObject; var structuralType = jsonContext.StructuralType; dict.ForEach(kvp => { var key = kvp.Key; var prop = structuralType.GetProperty(key); if (prop != null) { if (prop.IsDataProperty) { if (backingStore != null) { var dp = (DataProperty)prop; if (dp.IsComplexProperty) { var newCo = (IComplexObject)kvp.Value.ToObject(dp.ClrType); var co = (IComplexObject)backingStore[key]; var coBacking = co.ComplexAspect.BackingStore; newCo.ComplexAspect.BackingStore.ForEach(kvp2 => { coBacking[kvp2.Key] = kvp2.Value; }); } else { backingStore[key] = kvp.Value.ToObject(dp.ClrType); } } } else { // prop is a ComplexObject var np = (NavigationProperty)prop; if (kvp.Value.HasValues) { JsonContext newContext; if (np.IsScalar) { var nestedOb = (JObject)kvp.Value; newContext = new JsonContext() { JObject = nestedOb, ObjectType = prop.ClrType, Serializer = jsonContext.Serializer }; var entity = (IEntity)CreateAndPopulate(newContext); if (backingStore != null) { backingStore[key] = entity; } } else { var nestedArray = (JArray)kvp.Value; var navSet = (INavigationSet)TypeFns.CreateGenericInstance(typeof(NavigationSet <>), prop.ClrType); nestedArray.Cast <JObject>().ForEach(jo => { newContext = new JsonContext() { JObject = jo, ObjectType = prop.ClrType, Serializer = jsonContext.Serializer }; var entity = (IEntity)CreateAndPopulate(newContext); navSet.Add(entity); }); // add to existing nav set if there is one otherwise just set it. object tmp; if (backingStore.TryGetValue(key, out tmp)) { var backingNavSet = (INavigationSet)tmp; navSet.Cast <IEntity>().ForEach(e => backingNavSet.Add(e)); } else { navSet.NavigationProperty = np; navSet.ParentEntity = targetAspect.Entity; backingStore[key] = navSet; } } } else { // do nothing //if (!np.IsScalar) { // return TypeFns.ConstructGenericInstance(typeof(NavigationSet<>), prop.ClrType); //} else { // return null; //} } } } else { if (backingStore != null) { backingStore[key] = kvp.Value.ToObject <Object>(); } } }); }