예제 #1
0
        /// <summary>
        /// Gets a delegate which determines if the property or field should not be serialized based upon its value.
        /// </summary>
        /// <param name="member"></param>
        /// <returns>if has a value equivalent to the DefaultValueAttribute</returns>
        /// <remarks>
        /// This is useful for excluding serialization of default values.
        /// </remarks>
        public override ValueIgnoredDelegate GetValueIgnoredCallback(MemberInfo member)
        {
            Type objType = member.ReflectedType ?? member.DeclaringType;
            JsonSpecifiedPropertyAttribute specifiedPropertyAttr = TypeCoercionUtility.GetAttribute <JsonSpecifiedPropertyAttribute>(member);

            // look up specified property to see if exists
            GetterDelegate specifiedPropertyGetter = null;

            if (specifiedPropertyAttr != null && !String.IsNullOrEmpty(specifiedPropertyAttr.SpecifiedProperty))
            {
                PropertyInfo specProp = objType.GetProperty(specifiedPropertyAttr.SpecifiedProperty, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.FlattenHierarchy);

                // ensure is correct return type
                if (specProp != null && specProp.PropertyType == typeof(bool))
                {
                    specifiedPropertyGetter = DynamicMethodGenerator.GetPropertyGetter(specProp);
                }
            }

            DefaultValueAttribute defaultAttr = TypeCoercionUtility.GetAttribute <DefaultValueAttribute>(member);

            if (defaultAttr == null)
            {
                if (specifiedPropertyGetter == null)
                {
                    // no need to even create a delegate
                    return(null);
                }

                // create a delegate which simply calls the specified property
                return(delegate(object target, object value)
                {
                    return Object.Equals(false, specifiedPropertyGetter(target));
                });
            }

            // extract default value since cannot change (is constant in attribute)
            object defaultValue = defaultAttr.Value;

            if (specifiedPropertyGetter == null)
            {
                // create a specific delegate which only has to compare the default value to the current value
                return(delegate(object target, object value)
                {
                    return Object.Equals(defaultValue, value);
                });
            }

            // create a combined delegate which checks both states
            return(delegate(object target, object value)
            {
                return
                Object.Equals(defaultValue, value) ||
                Object.Equals(false, specifiedPropertyGetter(target));
            });
        }
예제 #2
0
        /// <summary>
        /// Gets the serialized name for the member.
        /// </summary>
        /// <param name="member"></param>
        /// <returns></returns>
        public override IEnumerable <DataName> GetName(MemberInfo member)
        {
            JsonNameAttribute attr = TypeCoercionUtility.GetAttribute <JsonNameAttribute>(member);

            // NOTE: JSON allows String.Empty as a valid property name
            if ((attr == null) || (attr.Name == null))
            {
                yield break;
            }

            yield return(new DataName(attr.Name));
        }
예제 #3
0
        /// <summary>
        /// Gets the serialized name for the member.
        /// </summary>
        /// <param name="member"></param>
        /// <returns></returns>
        public override IEnumerable <DataName> GetName(MemberInfo member)
        {
            if (member is Type)
            {
                XmlRootAttribute rootAttr = TypeCoercionUtility.GetAttribute <XmlRootAttribute>(member);
                if (rootAttr != null && !String.IsNullOrEmpty(rootAttr.ElementName))
                {
                    yield return(new DataName(rootAttr.ElementName, null, rootAttr.Namespace));
                }

                XmlTypeAttribute typeAttr = TypeCoercionUtility.GetAttribute <XmlTypeAttribute>(member);
                if (typeAttr != null && !String.IsNullOrEmpty(typeAttr.TypeName))
                {
                    yield return(new DataName(typeAttr.TypeName, null, typeAttr.Namespace));
                }

                yield break;
            }

            XmlElementAttribute elemAttr = TypeCoercionUtility.GetAttribute <XmlElementAttribute>(member);

            if (elemAttr != null && !String.IsNullOrEmpty(elemAttr.ElementName))
            {
                yield return(new DataName(elemAttr.ElementName, null, elemAttr.Namespace));
            }

            XmlAttributeAttribute attrAttr = TypeCoercionUtility.GetAttribute <XmlAttributeAttribute>(member);

            if (attrAttr != null && !String.IsNullOrEmpty(attrAttr.AttributeName))
            {
                yield return(new DataName(attrAttr.AttributeName, null, attrAttr.Namespace, true));
            }

            XmlArrayAttribute arrayAttr = TypeCoercionUtility.GetAttribute <XmlArrayAttribute>(member);

            if (arrayAttr != null && !String.IsNullOrEmpty(arrayAttr.ElementName))
            {
                // TODO: figure out a way to surface XmlArrayItemAttribute name too

                yield return(new DataName(arrayAttr.ElementName, null, arrayAttr.Namespace));
            }

            if (member is FieldInfo && ((FieldInfo)member).DeclaringType.IsEnum)
            {
                XmlEnumAttribute enumAttr = TypeCoercionUtility.GetAttribute <XmlEnumAttribute>(member);
                if (enumAttr != null && !String.IsNullOrEmpty(enumAttr.Name))
                {
                    yield return(new DataName(enumAttr.Name));
                }
            }
        }
예제 #4
0
        /// <summary>
        /// Gets the serialized name for the member.
        /// </summary>
        /// <param name="member"></param>
        /// <returns></returns>
        public override IEnumerable <DataName> GetName(MemberInfo member)
        {
            string    localName, ns;
            Attribute typeAttr;

            if (member is Type)
            {
                typeAttr = TypeCoercionUtility.GetAttribute(member, DataContractResolverStrategy.DataContractType);
                if (typeAttr == null)
                {
                    yield break;
                }

                localName = (string)DataContractResolverStrategy.DataContractNameGetter(typeAttr);
                ns        = (string)DataContractResolverStrategy.DataContractNamespaceGetter(typeAttr);

                if (!String.IsNullOrEmpty(localName))
                {
                    yield return(new DataName(localName, null, ns));
                }
                yield break;
            }

            typeAttr = TypeCoercionUtility.GetAttribute(member.DeclaringType, DataContractResolverStrategy.DataContractType);
            if (typeAttr == null)
            {
                yield break;
            }

            ns = (string)DataContractResolverStrategy.DataContractNamespaceGetter(typeAttr);

            Attribute memberAttr = TypeCoercionUtility.GetAttribute(member, DataContractResolverStrategy.DataMemberType);

            if (memberAttr == null)
            {
                yield break;
            }

            localName = (string)DataContractResolverStrategy.DataMemberNameGetter(memberAttr);

            if (!String.IsNullOrEmpty(localName))
            {
                // members inherit DataContract namespaces
                yield return(new DataName(localName, null, ns));
            }
        }
예제 #5
0
        /// <summary>
        /// Gets a delegate which determines if the property or field should not be serialized based upon its value.
        /// </summary>
        /// <param name="member"></param>
        /// <returns>if has a value equivalent to the DefaultValueAttribute or has a property named XXXSpecified which determines visibility</returns>
        /// <remarks>
        /// This is useful when default values need not be serialized.
        /// Under these situations XmlSerializer ignores properties based upon value:
        /// - DefaultValue: http://msdn.microsoft.com/en-us/library/system.componentmodel.defaultvalueattribute.aspx
        /// - Specified Properies: http://msdn.microsoft.com/en-us/library/bb402199.aspx
        /// - ShouldSerialize Methods: http://msdn.microsoft.com/en-us/library/53b8022e.aspx
        /// </remarks>
        public override ValueIgnoredDelegate GetValueIgnoredCallback(MemberInfo member)
        {
            Type objType = member.ReflectedType ?? member.DeclaringType;

            // look up specified property to see if exists
            GetterDelegate specifiedPropertyGetter = null;
            PropertyInfo   specProp = objType.GetProperty(member.Name + SpecifiedSuffix, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.FlattenHierarchy);

            // ensure is correct return type
            if (specProp != null && specProp.PropertyType == typeof(bool))
            {
                specifiedPropertyGetter = DynamicMethodGenerator.GetPropertyGetter(specProp);
            }

            // look up specified property to see if exists
            ProxyDelegate shouldSerializeProxy = null;
            MethodInfo    shouldSerialize      = objType.GetMethod(ShouldSerializePrefix + member.Name, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.FlattenHierarchy);

            // ensure is correct return type
            if (shouldSerialize != null && shouldSerialize.ReturnType == typeof(bool) && shouldSerialize.GetParameters().Length == 0)
            {
                shouldSerializeProxy = DynamicMethodGenerator.GetMethodProxy(shouldSerialize);
            }

            // to be most efficient must create a different delegate for each of 8 combinations so not performing extra work

            DefaultValueAttribute defaultAttr = TypeCoercionUtility.GetAttribute <DefaultValueAttribute>(member);

            if (defaultAttr == null)
            {
                if (specifiedPropertyGetter == null)
                {
                    if (shouldSerializeProxy == null)
                    {
                        // situation 1: only need to check if equal to null
                        return(delegate(object target, object value)
                        {
                            return (value == null);
                        });
                    }

                    // situation 2: create a delegate which simply calls the should serialize method
                    return(delegate(object target, object value)
                    {
                        return
                        (value == null) ||
                        Object.Equals(false, shouldSerializeProxy(target));
                    });
                }

                if (shouldSerializeProxy == null)
                {
                    // situation 3: create a delegate which simply calls the specified property
                    return(delegate(object target, object value)
                    {
                        return
                        (value == null) ||
                        Object.Equals(false, specifiedPropertyGetter(target));
                    });
                }

                // situation 4: create a delegate which calls both the specified property and the should serialize method
                return(delegate(object target, object value)
                {
                    return
                    (value == null) ||
                    Object.Equals(false, shouldSerializeProxy(target)) ||
                    Object.Equals(false, specifiedPropertyGetter(target));
                });
            }

            // extract default value since cannot change (is constant in attribute)
            object defaultValue = defaultAttr.Value;

            if (specifiedPropertyGetter == null)
            {
                if (shouldSerializeProxy == null)
                {
                    // situation 5: create a specific delegate which only has to compare the default value to the current value
                    return(delegate(object target, object value)
                    {
                        return
                        (value == null) ||
                        Object.Equals(defaultValue, value);
                    });
                }

                // situation 6: create a specific delegate which both compares to default value and calls should serialize method
                return(delegate(object target, object value)
                {
                    return
                    (value == null) ||
                    Object.Equals(defaultValue, value) ||
                    Object.Equals(false, shouldSerializeProxy(target));
                });
            }

            if (shouldSerializeProxy == null)
            {
                // situation 7: create a specific delegate which both compares to default value and checks specified property
                return(delegate(object target, object value)
                {
                    return
                    (value == null) ||
                    Object.Equals(defaultValue, value) ||
                    Object.Equals(false, specifiedPropertyGetter(target));
                });
            }

            // situation 8: create a combined delegate which checks all states
            return(delegate(object target, object value)
            {
                return
                (value == null) ||
                Object.Equals(defaultValue, value) ||
                Object.Equals(false, shouldSerializeProxy(target)) ||
                Object.Equals(false, specifiedPropertyGetter(target));
            });
        }