Example #1
0
        /// <summary>
        /// Initializes a new instance of the <see cref="JsonContainerContract"/> class.
        /// </summary>
        /// <param name="underlyingType">The underlying type for the contract.</param>
        internal JsonContainerContract(Type underlyingType)
            : base(underlyingType)
        {
            JsonContainerAttribute jsonContainerAttribute = JsonTypeReflector.GetJsonContainerAttribute(underlyingType);

            if (jsonContainerAttribute != null)
            {
                if (jsonContainerAttribute.ItemConverterType != null)
                {
                    ItemConverter = JsonConverterAttribute.CreateJsonConverterInstance(jsonContainerAttribute.ItemConverterType);
                }

                ItemIsReference           = jsonContainerAttribute._itemIsReference;
                ItemReferenceLoopHandling = jsonContainerAttribute._itemReferenceLoopHandling;
                ItemTypeNameHandling      = jsonContainerAttribute._itemTypeNameHandling;
            }
        }
        /// <summary>
        /// Creates a <see cref="JsonObjectContract"/> for the given type.
        /// </summary>
        /// <param name="objectType">Type of the object.</param>
        /// <returns>A <see cref="JsonObjectContract"/> for the given type.</returns>
        protected virtual JsonObjectContract CreateObjectContract(Type objectType)
        {
            JsonObjectContract contract = new JsonObjectContract(objectType);

            InitializeContract(contract);

            bool ignoreSerializableAttribute;

#if !(SILVERLIGHT || NETFX_CORE || PORTABLE)
            ignoreSerializableAttribute = IgnoreSerializableAttribute;
#else
            ignoreSerializableAttribute = true;
#endif

            contract.MemberSerialization = JsonTypeReflector.GetObjectMemberSerialization(contract.NonNullableUnderlyingType, ignoreSerializableAttribute);
            contract.Properties.AddRange(CreateProperties(contract.NonNullableUnderlyingType, contract.MemberSerialization));

            // check if a JsonConstructorAttribute has been defined and use that
            if (contract.NonNullableUnderlyingType.GetConstructors(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic).Any(c => c.IsDefined(typeof(JsonConstructorAttribute), true)))
            {
                ConstructorInfo constructor = GetAttributeConstructor(contract.NonNullableUnderlyingType);
                if (constructor != null)
                {
                    contract.OverrideConstructor = constructor;
                    contract.ConstructorParameters.AddRange(CreateConstructorParameters(constructor, contract.Properties));
                }
            }
            else if (contract.DefaultCreator == null || contract.DefaultCreatorNonPublic)
            {
                ConstructorInfo constructor = GetParametrizedConstructor(contract.NonNullableUnderlyingType);
                if (constructor != null)
                {
                    contract.ParametrizedConstructor = constructor;
                    contract.ConstructorParameters.AddRange(CreateConstructorParameters(constructor, contract.Properties));
                }
            }
            return(contract);
        }
        private void InitializeContract(JsonContract contract)
        {
            JsonContainerAttribute containerAttribute = JsonTypeReflector.GetJsonContainerAttribute(contract.NonNullableUnderlyingType);

            if (containerAttribute != null)
            {
                contract.IsReference = containerAttribute._isReference;
            }
#if !PocketPC && !NET20
            else
            {
                DataContractAttribute dataContractAttribute = JsonTypeReflector.GetDataContractAttribute(contract.NonNullableUnderlyingType);
                // doesn't have a null value
                if (dataContractAttribute != null && dataContractAttribute.IsReference)
                {
                    contract.IsReference = true;
                }
            }
#endif

            contract.Converter = ResolveContractConverter(contract.NonNullableUnderlyingType);

            // then see whether object is compadible with any of the built in converters
            contract.InternalConverter = JsonSerializer.GetMatchingConverter(BuiltInConverters, contract.NonNullableUnderlyingType);

            if (ReflectionUtils.HasDefaultConstructor(contract.CreatedType, true) ||
                contract.CreatedType.IsValueType())
            {
                contract.DefaultCreator = GetDefaultCreator(contract.CreatedType);

                contract.DefaultCreatorNonPublic = (!contract.CreatedType.IsValueType() &&
                                                    ReflectionUtils.GetDefaultConstructor(contract.CreatedType) == null);
            }

            ResolveCallbackMethods(contract, contract.NonNullableUnderlyingType);
        }
 /// <summary>
 /// Resolves the default <see cref="JsonConverter" /> for the contract.
 /// </summary>
 /// <param name="objectType">Type of the object.</param>
 /// <returns></returns>
 protected virtual JsonConverter ResolveContractConverter(Type objectType)
 {
     return(JsonTypeReflector.GetJsonConverter(objectType.GetCustomAttributeProvider(), objectType));
 }
        /// <summary>
        /// Gets the serializable members for the type.
        /// </summary>
        /// <param name="objectType">The type to get serializable members for.</param>
        /// <returns>The serializable members for the type.</returns>
        protected virtual List <MemberInfo> GetSerializableMembers(Type objectType)
        {
            bool ignoreSerializableAttribute;

#if !(SILVERLIGHT || NETFX_CORE || PORTABLE)
            ignoreSerializableAttribute = IgnoreSerializableAttribute;
#else
            ignoreSerializableAttribute = true;
#endif

            MemberSerialization memberSerialization = JsonTypeReflector.GetObjectMemberSerialization(objectType, ignoreSerializableAttribute);

            List <MemberInfo> allMembers = ReflectionUtils.GetFieldsAndProperties(objectType, BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Static)
                                           .Where(m => !ReflectionUtils.IsIndexedProperty(m)).ToList();

            List <MemberInfo> serializableMembers = new List <MemberInfo>();

            if (memberSerialization != MemberSerialization.Fields)
            {
#if !PocketPC && !NET20
                DataContractAttribute dataContractAttribute = JsonTypeReflector.GetDataContractAttribute(objectType);
#endif

                List <MemberInfo> defaultMembers = ReflectionUtils.GetFieldsAndProperties(objectType, DefaultMembersSearchFlags)
                                                   .Where(m => !ReflectionUtils.IsIndexedProperty(m)).ToList();

                foreach (MemberInfo member in allMembers)
                {
                    // exclude members that are compiler generated if set
                    if (SerializeCompilerGeneratedMembers || !member.IsDefined(typeof(CompilerGeneratedAttribute), true))
                    {
                        if (defaultMembers.Contains(member))
                        {
                            // add all members that are found by default member search
                            serializableMembers.Add(member);
                        }
                        else
                        {
                            // add members that are explicitly marked with JsonProperty/DataMember attribute
                            // or are a field if serializing just fields
                            if (JsonTypeReflector.GetAttribute <JsonPropertyAttribute>(member.GetCustomAttributeProvider()) != null)
                            {
                                serializableMembers.Add(member);
                            }
#if !PocketPC && !NET20
                            else if (dataContractAttribute != null && JsonTypeReflector.GetAttribute <DataMemberAttribute>(member.GetCustomAttributeProvider()) != null)
                            {
                                serializableMembers.Add(member);
                            }
#endif
                            else if (memberSerialization == MemberSerialization.Fields && member.MemberType() == MemberTypes.Field)
                            {
                                serializableMembers.Add(member);
                            }
                        }
                    }
                }

#if !PocketPC && !SILVERLIGHT && !NET20
                Type match;
                // don't include EntityKey on entities objects... this is a bit hacky
                if (objectType.AssignableToTypeName("System.Data.Objects.DataClasses.EntityObject", out match))
                {
                    serializableMembers = serializableMembers.Where(ShouldSerializeEntityMember).ToList();
                }
#endif
            }
            else
            {
                // serialize all fields
                foreach (MemberInfo member in allMembers)
                {
                    if (member.MemberType() == MemberTypes.Field)
                    {
                        serializableMembers.Add(member);
                    }
                }
            }

            return(serializableMembers);
        }
        private void SetPropertySettingsFromAttributes(JsonProperty property, ICustomAttributeProvider attributeProvider, string name, Type declaringType, MemberSerialization memberSerialization, out bool allowNonPublicAccess, out bool hasExplicitAttribute)
        {
            hasExplicitAttribute = false;

#if !PocketPC && !NET20
            DataContractAttribute dataContractAttribute = JsonTypeReflector.GetDataContractAttribute(declaringType);

            MemberInfo memberInfo = null;
#if !(NETFX_CORE || PORTABLE)
            memberInfo = attributeProvider as MemberInfo;
#else
            memberInfo = attributeProvider.UnderlyingObject as MemberInfo;
#endif

            DataMemberAttribute dataMemberAttribute;
            if (dataContractAttribute != null && memberInfo != null)
            {
                dataMemberAttribute = JsonTypeReflector.GetDataMemberAttribute((MemberInfo)memberInfo);
            }
            else
            {
                dataMemberAttribute = null;
            }
#endif

            JsonPropertyAttribute propertyAttribute = JsonTypeReflector.GetAttribute <JsonPropertyAttribute>(attributeProvider);
            if (propertyAttribute != null)
            {
                hasExplicitAttribute = true;
            }

            string mappedName;
            if (propertyAttribute != null && propertyAttribute.PropertyName != null)
            {
                mappedName = propertyAttribute.PropertyName;
            }
#if !PocketPC && !NET20
            else if (dataMemberAttribute != null && dataMemberAttribute.Name != null)
            {
                mappedName = dataMemberAttribute.Name;
            }
#endif
            else
            {
                mappedName = name;
            }

            property.PropertyName   = ResolvePropertyName(mappedName);
            property.UnderlyingName = name;

            if (propertyAttribute != null)
            {
                property.Required = propertyAttribute.Required;
                property.Order    = propertyAttribute._order;
            }
#if !PocketPC && !NET20
            else if (dataMemberAttribute != null)
            {
                property.Required = (dataMemberAttribute.IsRequired) ? Required.AllowNull : Required.Default;
                property.Order    = (dataMemberAttribute.Order != -1) ? (int?)dataMemberAttribute.Order : null;
            }
#endif
            else
            {
                property.Required = Required.Default;
            }

            bool hasJsonIgnoreAttribute = JsonTypeReflector.GetAttribute <JsonIgnoreAttribute>(attributeProvider) != null
#if !(SILVERLIGHT || NETFX_CORE || PORTABLE)
                                          || JsonTypeReflector.GetAttribute <NonSerializedAttribute>(attributeProvider) != null
#endif
            ;

            if (memberSerialization != MemberSerialization.OptIn)
            {
                // ignored if it has JsonIgnore or NonSerialized attributes
                property.Ignored = hasJsonIgnoreAttribute;
            }
            else
            {
                // ignored if it has JsonIgnore/NonSerialized or does not have DataMember or JsonProperty attributes
                property.Ignored =
                    hasJsonIgnoreAttribute ||
                    (propertyAttribute == null
#if !PocketPC && !NET20
                     && dataMemberAttribute == null
#endif
                    );
            }

            // resolve converter for property
            // the class type might have a converter but the property converter takes presidence
            property.Converter       = JsonTypeReflector.GetJsonConverter(attributeProvider, property.PropertyType);
            property.MemberConverter = JsonTypeReflector.GetJsonConverter(attributeProvider, property.PropertyType);

            DefaultValueAttribute defaultValueAttribute = JsonTypeReflector.GetAttribute <DefaultValueAttribute>(attributeProvider);
            property.DefaultValue = (defaultValueAttribute != null) ? defaultValueAttribute.Value : null;

            property.NullValueHandling      = (propertyAttribute != null) ? propertyAttribute._nullValueHandling : null;
            property.DefaultValueHandling   = (propertyAttribute != null) ? propertyAttribute._defaultValueHandling : null;
            property.ReferenceLoopHandling  = (propertyAttribute != null) ? propertyAttribute._referenceLoopHandling : null;
            property.ObjectCreationHandling = (propertyAttribute != null) ? propertyAttribute._objectCreationHandling : null;
            property.TypeNameHandling       = (propertyAttribute != null) ? propertyAttribute._typeNameHandling : null;
            property.IsReference            = (propertyAttribute != null) ? propertyAttribute._isReference : null;

            allowNonPublicAccess = false;
            if ((DefaultMembersSearchFlags & BindingFlags.NonPublic) == BindingFlags.NonPublic)
            {
                allowNonPublicAccess = true;
            }
            if (propertyAttribute != null)
            {
                allowNonPublicAccess = true;
            }
            if (memberSerialization == MemberSerialization.Fields)
            {
                allowNonPublicAccess = true;
            }

#if !PocketPC && !NET20
            if (dataMemberAttribute != null)
            {
                allowNonPublicAccess = true;
                hasExplicitAttribute = true;
            }
#endif
        }