/// <summary> /// Read JSON string to the object. /// </summary> /// <param name="reader">JSON reader.</param> /// <param name="objectType">Object type.</param> /// <param name="existingValue">Existing value.</param> /// <param name="serializer">Json serializer</param> /// <returns>Deserialized object.</returns> /// <remarks> /// 1. Check if this is an array or a single element. /// If Array, deserialize each element as DirectoryObject and return the list /// 2. Deserialize using the default property set /// 3. Find the non-deserialized properties and add them to the Dictionary. /// </remarks> public override object ReadJson( JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) { if (reader.TokenType == JsonToken.StartArray) { JToken jsonToken = JArray.ReadFrom(reader); List<JToken> jsonTokens = jsonToken.ToList(); // This converter can only handle an array of graph objects. // Not native types. When deserializing an expanded link, all linked objects will be // deserialized as GraphObject. ChangeTrackingCollection<GraphObject> resultObjects = new ChangeTrackingCollection<GraphObject>(); AadJsonConverter jsonConverter = new AadJsonConverter(); foreach (JToken arrayToken in jsonTokens) { GraphObject resultElement = JsonConvert.DeserializeObject( arrayToken.ToString(), typeof(GraphObject), jsonConverter) as GraphObject; resultObjects.Add(resultElement); } return resultObjects; } // Load the JSON into a JsonObject so that we can inspect the odata.type property. Object resultObject; JObject jsonObject = JObject.Load(reader); List<JProperty> jsonProperties = jsonObject.Properties().ToList(); JProperty odataTypeProperty = jsonProperties.FirstOrDefault(x => x.Name == Constants.OdataTypeKey); // If there is odata.type value, use that to find the type to be deserialized into. // If not, use the type that was passed to the de-serializer. Type resultObjectType; if (odataTypeProperty != null && SerializationHelper.TryGetImplementationForAadType( odataTypeProperty.Value.ToString(), out resultObjectType) && typeof(GraphObject).IsAssignableFrom(resultObjectType)) { resultObject = Activator.CreateInstance(resultObjectType) as GraphObject; } else { resultObjectType = objectType; resultObject = Activator.CreateInstance(resultObjectType); } // Deserialize all known properties using the default JSON.NET serializer resultObject = JsonConvert.DeserializeObject(jsonObject.ToString(), resultObjectType); // TODO: If the odata type is null, should still try to deserialize additional values using // the graphObjectType. GraphObject graphObject = resultObject as GraphObject; if (graphObject != null && odataTypeProperty != null) { Dictionary<string, PropertyInfo> propertyNameToInfoMap = this.GetPropertyInfosForAadType(odataTypeProperty.Value.ToString(), resultObjectType); foreach (JProperty jsonProperty in jsonProperties) { PropertyInfo propertyInfo; if (!propertyNameToInfoMap.TryGetValue(jsonProperty.Name, out propertyInfo)) { graphObject.NonSerializedProperties[jsonProperty.Name] = jsonProperty.Value.ToString(); } } } return graphObject; }
/// <summary> /// Read JSON string to the object. /// </summary> /// <param name="reader">JSON reader.</param> /// <param name="objectType">Object type.</param> /// <param name="existingValue">Existing value.</param> /// <param name="serializer">Json serializer</param> /// <returns>Deserialized object.</returns> /// <remarks> /// 1. Check if this is an array or a single element. /// If Array, deserialize each element as DirectoryObject and return the list /// 2. Deserialize using the default property set /// 3. Find the non-deserialized properties and add them to the Dictionary. /// </remarks> public override object ReadJson( JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) { if (reader.TokenType == JsonToken.StartArray) { JToken jsonToken = JArray.ReadFrom(reader); List <JToken> jsonTokens = jsonToken.ToList(); // This converter can only handle an array of graph objects. // Not native types. When deserializing an expanded link, all linked objects will be // deserialized as GraphObject. ChangeTrackingCollection <GraphObject> resultObjects = new ChangeTrackingCollection <GraphObject>(); AadJsonConverter jsonConverter = new AadJsonConverter(); foreach (JToken arrayToken in jsonTokens) { GraphObject resultElement = JsonConvert.DeserializeObject( arrayToken.ToString(), typeof(GraphObject), jsonConverter) as GraphObject; resultObjects.Add(resultElement); } return(resultObjects); } // Load the JSON into a JsonObject so that we can inspect the odata.type property. Object resultObject; JObject jsonObject = JObject.Load(reader); List <JProperty> jsonProperties = jsonObject.Properties().ToList(); JProperty odataTypeProperty = jsonProperties.FirstOrDefault(x => x.Name == Constants.OdataTypeKey); // If there is odata.type value, use that to find the type to be deserialized into. // If not, use the type that was passed to the de-serializer. Type resultObjectType; if (odataTypeProperty != null && SerializationHelper.TryGetImplementationForAadType( odataTypeProperty.Value.ToString(), out resultObjectType) && typeof(GraphObject).IsAssignableFrom(resultObjectType)) { resultObject = Activator.CreateInstance(resultObjectType) as GraphObject; } else { resultObjectType = objectType; resultObject = Activator.CreateInstance(resultObjectType); } // Deserialize all known properties using the default JSON.NET serializer resultObject = JsonConvert.DeserializeObject(jsonObject.ToString(), resultObjectType); // TODO: If the odata type is null, should still try to deserialize additional values using // the graphObjectType. GraphObject graphObject = resultObject as GraphObject; if (graphObject != null && odataTypeProperty != null) { Dictionary <string, PropertyInfo> propertyNameToInfoMap = this.GetPropertyInfosForAadType(odataTypeProperty.Value.ToString(), resultObjectType); foreach (JProperty jsonProperty in jsonProperties) { PropertyInfo propertyInfo; if (!propertyNameToInfoMap.TryGetValue(jsonProperty.Name, out propertyInfo)) { graphObject.NonSerializedProperties[jsonProperty.Name] = jsonProperty.Value.ToString(); } } } return(graphObject); }