private static Action <T, JsonObject> GetDocumentDeserializePropertyAction(string memberName, Action <object, object> setFunc) { return((v, j) => { if (j.ContainsKey(Message.TYPE_KEY) && j[Message.TYPE_KEY] is string) { var mediaType = MediaType.Parse((string)j[Message.TYPE_KEY]); object value; Type concreteType; if (mediaType.IsJson) { JsonObject propertyJsonObject = null; if (j.ContainsKey(memberName) && j[memberName] is JsonObject) { propertyJsonObject = (JsonObject)j[memberName]; } if (TypeUtil.TryGetTypeForMediaType(mediaType, out concreteType)) { if (propertyJsonObject != null) { value = JsonSerializer.ParseJson(concreteType, propertyJsonObject); } else { value = TypeUtil.CreateInstance(concreteType); } } else if (propertyJsonObject != null) { value = new JsonDocument(propertyJsonObject, mediaType); } else { value = new JsonDocument(mediaType); } } else { string propertyValue = null; if (j.ContainsKey(memberName) && j[memberName] is string) { propertyValue = (string)j[memberName]; } if (TypeUtil.TryGetTypeForMediaType(mediaType, out concreteType)) { if (propertyValue != null) { var parseFunc = TypeUtil.GetParseFuncForType(concreteType); value = parseFunc(propertyValue); } else { value = TypeUtil.CreateInstance(concreteType); } } else { value = new PlainDocument(propertyValue, mediaType); } } if (value != null) { setFunc(v, value); } } }); }
private static Action <T, JsonObject> GetPropertyDeserializationAction(Type propertyType, MethodInfo setMethod, string memberName, object defaultValue) { var setFunc = TypeUtil.BuildSetAccessor(setMethod); Action <T, JsonObject> deserializePropertyAction = null; var isNullable = false; if (propertyType.IsGenericType && propertyType.GetGenericTypeDefinition() == typeof(Nullable <>)) { propertyType = propertyType.GetGenericArguments().First(); isNullable = true; } if (propertyType.IsArray) { propertyType = propertyType.GetElementType(); if (propertyType == typeof(string)) { deserializePropertyAction = (v, j) => { var value = j.GetArrayOrNull(propertyType, memberName, i => (string)i); if (value != null) { setFunc(v, value); } }; } else if (propertyType.IsEnum) { deserializePropertyAction = (v, j) => { var value = j.GetEnumArrayOrNull(propertyType, memberName) ?? defaultValue; if (value != null) { setFunc(v, value); } }; } else if (propertyType.IsAbstract) { if (propertyType == typeof(Document)) { // Determine the type of the property using the // envelope content/resource Mime Type deserializePropertyAction = (v, j) => { if (j.ContainsKey(DocumentCollection.ITEM_TYPE_KEY) && j[DocumentCollection.ITEM_TYPE_KEY] is string) { var mediaType = MediaType.Parse((string)j[DocumentCollection.ITEM_TYPE_KEY]); if (j.ContainsKey(memberName) && j[memberName] is IEnumerable) { Array value; Type itemPropertyType; if (TypeUtil.TryGetTypeForMediaType(mediaType, out itemPropertyType)) { value = j.GetArrayOrNull(propertyType, memberName, i => JsonSerializer.ParseJson(itemPropertyType, (JsonObject)i)); } else if (mediaType.IsJson) { value = j.GetArrayOrNull(propertyType, memberName, i => new JsonDocument((JsonObject)i, mediaType)); } else { value = j.GetArrayOrNull(propertyType, memberName, i => new PlainDocument(i.ToString(), mediaType)); } if (value != null) { setFunc(v, value); } } } }; } else { throw new NotSupportedException(string.Format("The type '{0}' of the property '{1}' is not supported", propertyType, memberName)); } } else if (TypeUtil.IsDataContractType(propertyType)) { // In this case, the dictionary has a JsonObject entry // for the property, so it must be parsed deserializePropertyAction = (v, j) => { if (j.ContainsKey(memberName) && j[memberName] is IEnumerable) { var value = j.GetArrayOrNull(propertyType, memberName, i => JsonSerializer.ParseJson(propertyType, (JsonObject)i)); if (value != null) { setFunc(v, value); } } }; } else { try { var parseFunc = TypeUtil.GetParseFuncForType(propertyType); deserializePropertyAction = (v, j) => { var value = j.GetArrayOrNull(propertyType, memberName, i => parseFunc((string)i)); if (value != null) { setFunc(v, value); } }; } catch (ArgumentException) { throw new NotSupportedException(string.Format("The type '{0}' of the property '{1}' is not supported", propertyType, memberName)); } } } else if (propertyType.IsEnum) { deserializePropertyAction = (v, j) => { var value = j.GetEnumValueOrNull(propertyType, memberName) ?? defaultValue; if (isNullable || value != null) { setFunc(v, value); } }; } else if (propertyType == typeof(int)) { deserializePropertyAction = (v, j) => { var value = j.GetValueOrNull <int>(memberName, o => Convert.ToInt32(o)) ?? defaultValue; if (isNullable || value != null) { setFunc(v, value); } }; } else if (propertyType == typeof(long)) { deserializePropertyAction = (v, j) => { var value = j.GetValueOrNull <long>(memberName) ?? defaultValue; if (isNullable || value != null) { setFunc(v, value); } }; } else if (propertyType == typeof(double)) { deserializePropertyAction = (v, j) => { var value = j.GetValueOrNull <double>(memberName, o => Convert.ToDouble(o)) ?? defaultValue; if (isNullable || value != null) { setFunc(v, value); } }; } else if (propertyType == typeof(bool)) { deserializePropertyAction = (v, j) => { var value = j.GetValueOrNull <bool>(memberName) ?? defaultValue; if (isNullable || value != null) { setFunc(v, value); } }; } else if (propertyType == typeof(string)) { deserializePropertyAction = (v, j) => { var value = j.GetValueOrDefault <string>(memberName) ?? defaultValue; if (value != null) { setFunc(v, value); } }; } else if (propertyType == typeof(Uri)) { deserializePropertyAction = (v, j) => { var value = j.GetValueOrDefault <Uri>(memberName, o => new Uri(o.ToString())) ?? defaultValue; if (value != null) { setFunc(v, value); } }; } else if (typeof(IDictionary <string, string>).IsAssignableFrom(propertyType)) { // Metadata property deserializePropertyAction = (v, j) => { var value = j.GetValueOrDefault <IDictionary <string, string> >(memberName, d => ((IDictionary <string, object>)d).ToDictionary(e => e.Key, e => (string)e.Value)); if (value != null) { setFunc(v, value); } }; } else if (typeof(IDictionary <string, object>).IsAssignableFrom(propertyType)) { // Metadata property deserializePropertyAction = (v, j) => { var value = j.GetValueOrDefault <IDictionary <string, object> >(memberName, d => ((IDictionary <string, object>)d).ToDictionary(e => e.Key, e => e.Value)); if (value != null) { setFunc(v, value); } }; } else if (propertyType.IsAbstract) { if (propertyType == typeof(Document)) { // Determine the type of the property using the // envelope content/resource Mime Type deserializePropertyAction = GetDocumentDeserializePropertyAction(memberName, setFunc); } else if (propertyType == typeof(Authentication)) { // Determine the type of the property using the // session Authentication property deserializePropertyAction = GetAuthenticationDeserializePropertyAction(memberName, setFunc); } else { throw new NotSupportedException(string.Format("The type '{0}' of the property '{1}' is not supported", propertyType, memberName)); } } else if (TypeUtil.IsDataContractType(propertyType)) { // In this case, the dictionary has a JsonObject entry // for the property, so it must be parsed deserializePropertyAction = (v, j) => { if (j.ContainsKey(memberName) && j[memberName] is JsonObject) { var propertyJsonObject = (JsonObject)j[memberName]; var value = JsonSerializer.ParseJson(propertyType, propertyJsonObject) ?? defaultValue; if (isNullable || value != null) { setFunc(v, value); } } }; } else { // Checks if the type has a static Parse function try { var parseFunc = TypeUtil.GetParseFuncForType(propertyType); deserializePropertyAction = (v, j) => { var value = j.GetValueOrNull(memberName, parseFunc) ?? defaultValue; if (isNullable || value != null) { setFunc(v, value); } }; } catch (ArgumentException) { throw new NotSupportedException(string.Format("The type '{0}' of the property '{1}' is not supported", propertyType, memberName)); } } return(deserializePropertyAction); }