예제 #1
0
        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);
                    }
                }
            });
        }
예제 #2
0
        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);
        }