/// <summary>
        /// Serializes the member.
        /// </summary>
        /// <param name="context">The context.</param>
        /// <param name="memberValue">The member value.</param>
        public override void SerializeMember(ISerializationContext context, MemberValue memberValue)
        {
            base.SerializeMember(context, memberValue);

            var value = memberValue.Value;
            if (value != null)
            {
                var valueType = value.GetType();
                if (valueType.IsGenericTypeEx())
                {
                    if (valueType.GetGenericTypeDefinitionEx() == typeof(KeyValuePair<,>))
                    {
                        var keyProperty = valueType.GetPropertyEx("Key");
                        var valueProperty = valueType.GetPropertyEx("Value");

                        var kvpKey = keyProperty.GetValue(value, null);
                        var kvpValue = valueProperty.GetValue(value, null);

                        var finalValue = string.Format("{0}{1}{2}{1}{3}{1}{4}{1}{5}", Prefix, Splitter,
                            keyProperty.PropertyType, valueProperty.PropertyType,
                            ObjectToStringHelper.ToString(kvpKey), ObjectToStringHelper.ToString(kvpValue));

                        memberValue.Value = finalValue;
                    }
                }
            }
        }
        /// <summary>
        /// Deserializes the member.
        /// </summary>
        /// <param name="context">The context.</param>
        /// <param name="memberValue">The member value.</param>
        public override void DeserializeMember(ISerializationContext context, MemberValue memberValue)
        {
            var valueAsString = memberValue.Value as string;
            if (!string.IsNullOrEmpty(valueAsString))
            {
                if (valueAsString.StartsWith(Prefix))
                {
                    var splittedValues = valueAsString.Split(new[] { Splitter }, StringSplitOptions.None);

                    var keyValuePairType = typeof(KeyValuePair<,>);
                    var keyType = TypeCache.GetTypeWithoutAssembly(splittedValues[1]);
                    var valueType = TypeCache.GetTypeWithoutAssembly(splittedValues[2]);
                    var keyValue = splittedValues[3];
                    var valueValue = splittedValues[4];

                    // TODO: consider caching
                    var keyValuePairGenericType = keyValuePairType.MakeGenericType(keyType, valueType);

                    var key = StringToObjectHelper.ToRightType(keyType, keyValue);
                    var value = StringToObjectHelper.ToRightType(valueType, valueValue);

                    var keyValuePair = Activator.CreateInstance(keyValuePairGenericType, new [] { key, value });

                    memberValue.Value = keyValuePair;
                }
            }

            base.DeserializeMember(context, memberValue);
        }
        public override void DeserializeMember(ISerializationContext context, MemberValue memberValue)
        {
            if (string.Equals(memberValue.Name, "ProjectTypes"))
            {
                // TODO: Match the list with WP8 => WP80 somehow?
            }

            base.DeserializeMember(context, memberValue);
        }
 /// <summary>
 /// Returns whether the serializer should serialize the member using <c>ToString(IFormatProvider)</c> and <c>Parse(string, IFormatProvider)</c>.
 /// </summary>
 /// <returns><c>true</c> if the member should be serialized using parse, <c>false</c> if not. Return <c>null</c> if the serializer should decide automatically.</returns>
 public virtual bool? ShouldSerializeMemberUsingParse(MemberValue memberValue)
 {
     return null;
 }
Exemple #5
0
        /// <summary>
        /// Gets the member value.
        /// </summary>
        /// <param name="model">The model.</param>
        /// <param name="memberName">Name of the member.</param>
        /// <param name="modelInfo">The model information.</param>
        /// <returns>MemberValue.</returns>
        public virtual MemberValue GetMemberValue(object model, string memberName, SerializationModelInfo modelInfo)
        {
            var modelType = model.GetType();

            try
            {
                var modelEditor = model as IModelEditor;
                if (modelEditor != null && modelInfo.CatelPropertyNames.Contains(memberName))
                {
                    var memberMetadata = modelInfo.CatelPropertiesByName[memberName];
                    var actualPropertyValue = modelEditor.GetValueFastButUnsecure(memberName);

                    var propertyValue = new MemberValue(SerializationMemberGroup.CatelProperty, modelType, memberMetadata.MemberType, 
                        memberMetadata.MemberName, memberMetadata.MemberNameForSerialization, actualPropertyValue);
                    return propertyValue;
                }

                if (modelInfo.PropertiesByName.ContainsKey(memberName))
                {
                    var memberMetadata = modelInfo.PropertiesByName[memberName];

                    object value = null;
                    var get = false;

                    var propertySerializable = model as IPropertySerializable;
                    if (propertySerializable != null)
                    {
                        get = propertySerializable.GetPropertyValue(memberName, ref value);
                    }

                    if (!get)
                    {
                        value = ((PropertyInfo)memberMetadata.Tag).GetValue(model, null);
                    }

                    var propertyValue = new MemberValue(SerializationMemberGroup.RegularProperty, modelType, memberMetadata.MemberType, 
                        memberMetadata.MemberName, memberMetadata.MemberNameForSerialization, value);
                    return propertyValue;
                }

                if (modelInfo.FieldsByName.ContainsKey(memberName))
                {
                    var memberMetadata = modelInfo.FieldsByName[memberName];

                    object value = null;
                    var get = false;

                    var fieldSerializable = model as IFieldSerializable;
                    if (fieldSerializable != null)
                    {
                        get = fieldSerializable.GetFieldValue(memberName, ref value);
                    }

                    if (!get)
                    {
                        value = ((FieldInfo)memberMetadata.Tag).GetValue(model);
                    }

                    var fieldValue = new MemberValue(SerializationMemberGroup.Field, modelType, memberMetadata.MemberType, 
                        memberMetadata.MemberName, memberMetadata.MemberNameForSerialization, value);
                    return fieldValue;
                }
            }
            catch (Exception ex)
            {
                Log.Warning(ex, "Failed to get value of member '{0}.{1}', skipping item during serialization", modelType.GetSafeFullName(false), memberName);
            }

            return null;
        }
Exemple #6
0
        /// <summary>
        /// Sets the member value.
        /// </summary>
        /// <param name="model">The model.</param>
        /// <param name="member">The member.</param>
        /// <param name="modelInfo">The model information.</param>
        public virtual void SetMemberValue(object model, MemberValue member, SerializationModelInfo modelInfo)
        {
            var modelType = model.GetType();

            try
            {
                var modelEditor = model as IModelEditor;
                if (modelEditor != null && modelInfo.CatelPropertyNames.Contains(member.Name))
                {
                    modelEditor.SetValueFastButUnsecure(member.Name, member.Value);
                }
                else if (modelInfo.PropertyNames.Contains(member.Name))
                {
                    var set = false;

                    var propertySerializable = model as IPropertySerializable;
                    if (propertySerializable != null)
                    {
                        set = propertySerializable.SetPropertyValue(member.Name, member.Value);
                    }

                    if (!set)
                    {
                        var memberMetadata = modelInfo.PropertiesByName[member.Name];
                        if (memberMetadata != null)
                        {
                            ((PropertyInfo)memberMetadata.Tag).SetValue(model, member.Value, null);
                            set = true;
                        }
                    }

                    if (!set)
                    {
                        Log.Warning("Failed to set property '{0}.{1}' because the member cannot be found on the model", modelType.GetSafeFullName(false), member.Name);
                    }
                }
                else if (modelInfo.FieldNames.Contains(member.Name))
                {
                    var set = false;

                    var fieldSerializable = model as IFieldSerializable;
                    if (fieldSerializable != null)
                    {
                        set = fieldSerializable.SetFieldValue(member.Name, member.Value);
                    }

                    if (!set)
                    {
                        var memberMetadata = modelInfo.FieldsByName[member.Name];
                        if (memberMetadata != null)
                        {
                            ((FieldInfo)memberMetadata.Tag).SetValue(model, member.Value);
                            set = true;
                        }
                    }

                    if (!set)
                    {
                        Log.Warning("Failed to set field '{0}.{1}' because the member cannot be found on the model", modelType.GetSafeFullName(false), member.Name);
                    }
                }
            }
            catch (Exception ex)
            {
                Log.Warning(ex, "Failed to populate '{0}.{1}', setting the member value threw an exception", modelType.GetSafeFullName(false), member.Name);
            }
        }
 /// <summary>
 /// Serializes the member.
 /// </summary>
 /// <param name="context">The context.</param>
 /// <param name="memberValue">The member value.</param>
 /// <returns>The deserialized member value.</returns>
 protected abstract void SerializeMember(ISerializationContext <TSerializationContextInfo> context, MemberValue memberValue);
 /// <summary>
 /// Determines whether the specified member value is a root collection.
 /// </summary>
 /// <param name="context">The context.</param>
 /// <param name="memberValue">The member value.</param>
 /// <returns><c>true</c> if the specified member value is a root collection; otherwise, <c>false</c>.</returns>
 protected virtual bool IsRootCollection(ISerializationContext <TSerializationContextInfo> context, MemberValue memberValue)
 {
     return(IsRootObject(context, memberValue, x => ShouldSerializeAsCollection(x)));
 }
        /// <summary>
        /// Determines whether the specified member value is a root object.
        /// </summary>
        /// <param name="context">The context.</param>
        /// <param name="memberValue">The member value.</param>
        /// <param name="predicate">The predicate.</param>
        /// <returns><c>true</c> if the specified member value is a root object; otherwise, <c>false</c>.</returns>
        protected virtual bool IsRootObject(ISerializationContext <TSerializationContextInfo> context, MemberValue memberValue, Func <MemberValue, bool> predicate)
        {
            if (context.Depth > 0)
            {
                return(false);
            }

            if (!ReferenceEquals(context.Model, memberValue.Value))
            {
                return(false);
            }

            if (!predicate(memberValue))
            {
                return(false);
            }

            return(true);
        }
Exemple #10
0
        /// <summary>
        /// Sets the member value.
        /// </summary>
        /// <param name="model">The model.</param>
        /// <param name="member">The member.</param>
        /// <param name="modelInfo">The model information.</param>
        public virtual void SetMemberValue(object model, MemberValue member, SerializationModelInfo modelInfo)
        {
            var modelType = model.GetType();

            try
            {
                var modelEditor = model as IModelEditor;
                if (modelEditor != null && modelInfo.CatelPropertyNames.Contains(member.Name))
                {
                    modelEditor.SetValueFastButUnsecure(member.Name, member.Value);
                }
                else if (modelInfo.PropertyNames.Contains(member.Name))
                {
                    var set = false;

                    var propertySerializable = model as IPropertySerializable;
                    if (propertySerializable != null)
                    {
                        set = propertySerializable.SetPropertyValue(member.Name, member.Value);
                    }

                    if (!set)
                    {
                        var memberMetadata = modelInfo.PropertiesByName[member.Name];
                        if (memberMetadata != null)
                        {
                            ((PropertyInfo)memberMetadata.Tag).SetValue(model, member.Value, null);
                            set = true;
                        }
                    }

                    if (!set)
                    {
                        Log.Warning("Failed to set property '{0}.{1}' because the member cannot be found on the model", modelType.GetSafeFullName(), member.Name);
                    }
                }
                else if (modelInfo.FieldNames.Contains(member.Name))
                {
                    var set = false;

                    var fieldSerializable = model as IFieldSerializable;
                    if (fieldSerializable != null)
                    {
                        set = fieldSerializable.SetFieldValue(member.Name, member.Value);
                    }

                    if (!set)
                    {
                        var memberMetadata = modelInfo.FieldsByName[member.Name];
                        if (memberMetadata != null)
                        {
                            ((FieldInfo)memberMetadata.Tag).SetValue(model, member.Value);
                            set = true;
                        }
                    }

                    if (!set)
                    {
                        Log.Warning("Failed to set field '{0}.{1}' because the member cannot be found on the model", modelType.GetSafeFullName(), member.Name);
                    }
                }
            }
            catch (Exception ex)
            {
                Log.Warning(ex, "Failed to populate '{0}.{1}', setting the member value threw an exception", modelType.GetSafeFullName(), member.Name);
            }
        }
Exemple #11
0
        /// <summary>
        /// Gets the member value.
        /// </summary>
        /// <param name="model">The model.</param>
        /// <param name="memberName">Name of the member.</param>
        /// <param name="modelInfo">The model information.</param>
        /// <returns>MemberValue.</returns>
        public virtual MemberValue GetMemberValue(object model, string memberName, SerializationModelInfo modelInfo)
        {
            var modelType = model.GetType();

            try
            {
                var modelEditor = model as IModelEditor;
                if (modelEditor != null && modelInfo.CatelPropertyNames.Contains(memberName))
                {
                    var memberMetadata      = modelInfo.CatelPropertiesByName[memberName];
                    var actualPropertyValue = modelEditor.GetValueFastButUnsecure(memberName);

                    var propertyValue = new MemberValue(SerializationMemberGroup.CatelProperty, modelType, memberMetadata.MemberType,
                                                        memberMetadata.MemberName, memberMetadata.MemberNameForSerialization, actualPropertyValue);
                    return(propertyValue);
                }

                if (modelInfo.PropertiesByName.ContainsKey(memberName))
                {
                    var memberMetadata = modelInfo.PropertiesByName[memberName];

                    object value = null;
                    var    get   = false;

                    var propertySerializable = model as IPropertySerializable;
                    if (propertySerializable != null)
                    {
                        get = propertySerializable.GetPropertyValue(memberName, ref value);
                    }

                    if (!get)
                    {
                        value = ((PropertyInfo)memberMetadata.Tag).GetValue(model, null);
                    }

                    var propertyValue = new MemberValue(SerializationMemberGroup.RegularProperty, modelType, memberMetadata.MemberType,
                                                        memberMetadata.MemberName, memberMetadata.MemberNameForSerialization, value);
                    return(propertyValue);
                }

                if (modelInfo.FieldsByName.ContainsKey(memberName))
                {
                    var memberMetadata = modelInfo.FieldsByName[memberName];

                    object value = null;
                    var    get   = false;

                    var fieldSerializable = model as IFieldSerializable;
                    if (fieldSerializable != null)
                    {
                        get = fieldSerializable.GetFieldValue(memberName, ref value);
                    }

                    if (!get)
                    {
                        value = ((FieldInfo)memberMetadata.Tag).GetValue(model);
                    }

                    var fieldValue = new MemberValue(SerializationMemberGroup.Field, modelType, memberMetadata.MemberType,
                                                     memberMetadata.MemberName, memberMetadata.MemberNameForSerialization, value);
                    return(fieldValue);
                }
            }
            catch (Exception ex)
            {
                Log.Warning(ex, "Failed to get value of member '{0}.{1}', skipping item during serialization", modelType.GetSafeFullName(), memberName);
            }

            return(null);
        }
        /// <summary>
        /// Deserializes the object using the <c>Parse(string, IFormatProvider)</c> method.
        /// </summary>
        /// <returns>The deserialized object.</returns>
        protected virtual string SerializeUsingObjectToString(ISerializationContext <TSerializationContextInfo> context, MemberValue memberValue)
        {
            var toStringMethod = GetObjectToStringMethod(memberValue.GetBestMemberType());

            if (toStringMethod is null)
            {
                return(null);
            }

            try
            {
                var stringValue = (string)toStringMethod.Invoke(memberValue.Value, new object[] { context.Configuration.Culture });
                return(stringValue);
            }
            catch (Exception ex)
            {
                Log.Warning(ex, $"Failed to serialize type '{memberValue.GetBestMemberType().GetSafeFullName(false)}' using ToString(IFormatProvider)");
                return(null);
            }
        }
        /// <summary>
        /// Ends member serialization by invoking all the right events and running the modifiers.
        /// </summary>
        /// <param name="context">The serialization context.</param>
        /// <param name="member">The member that has been deserialized.</param>
        protected void EndMemberSerialization(ISerializationContext <TSerializationContextInfo> context, MemberValue member)
        {
            SerializeMember(context, member);

            AfterSerializeMember(context, member);

            SerializedMember?.Invoke(this, new MemberSerializationEventArgs(context, member));
        }
 /// <summary>
 /// Called after the serializer has serialized a specific member.
 /// </summary>
 /// <param name="context">The context.</param>
 /// <param name="memberValue">The member value.</param>
 protected virtual void AfterSerializeMember(ISerializationContext <TSerializationContextInfo> context, MemberValue memberValue)
 {
 }
 /// <summary>
 /// Determines whether the specified member should be ignored.
 /// </summary>
 /// <param name="context">The context.</param>
 /// <param name="model">The model.</param>
 /// <param name="memberValue">The member value.</param>
 /// <returns><c>true</c> if the property should be ignored, <c>false</c> otherwise.</returns>
 public virtual bool ShouldIgnoreMember(ISerializationContext context, IModel model, MemberValue memberValue)
 {
     return false;
 }
        /// <summary>
        /// Returns whether the member value should be serialized using <c>ToString(IFormatProvider)</c> and deserialized using <c>Parse(string, IFormatProvider)</c>.
        /// </summary>
        /// <param name="memberValue">The member value.</param>
        /// <param name="checkActualMemberType">if set to <c>true</c>, check the actual member type.</param>
        /// <returns>
        ///   <c>true</c> if the member should be serialized using parse.
        /// </returns>
        protected virtual bool ShouldSerializeUsingParseAndToString(MemberValue memberValue, bool checkActualMemberType)
        {
            var cacheKey = $"{memberValue.ModelTypeName}|{memberValue.Name}|{checkActualMemberType}";

            return(_shouldSerializeUsingParseCache.GetFromCacheOrFetch(cacheKey, () =>
            {
                var serializerModifiers = SerializationManager.GetSerializerModifiers(memberValue.ModelType);

                var useParseAndToString = false;

                var fieldInfo = memberValue.ModelType.GetFieldEx(memberValue.Name);
                if (fieldInfo != null)
                {
                    useParseAndToString = fieldInfo.IsDecoratedWithAttribute <SerializeUsingParseAndToStringAttribute>();
                }

                if (!useParseAndToString)
                {
                    var propertyInfo = memberValue.ModelType.GetPropertyEx(memberValue.Name);
                    if (propertyInfo != null)
                    {
                        useParseAndToString = propertyInfo.IsDecoratedWithAttribute <SerializeUsingParseAndToStringAttribute>();
                    }
                }

                // Note: serializer modifiers can always win
                foreach (var serializerModifier in serializerModifiers)
                {
                    var value = serializerModifier.ShouldSerializeMemberUsingParse(memberValue);
                    if (value.HasValue)
                    {
                        if (!value.Value)
                        {
                            return false;
                        }

                        // At least 1 serializer modifier wants this to be using parse and tostring
                        useParseAndToString = true;
                    }
                }

                if (!useParseAndToString)
                {
                    return false;
                }

                var memberType = checkActualMemberType ? memberValue.ActualMemberType : memberValue.MemberType;
                if (memberType is null)
                {
                    memberType = memberValue.MemberType;
                }

                var toStringMethod = GetObjectToStringMethod(memberType);
                if (toStringMethod is null)
                {
                    return false;
                }

                var parseMethod = GetObjectParseMethod(memberType);
                if (parseMethod is null)
                {
                    return false;
                }

                return true;
            }));
        }
 /// <summary>
 /// Allows the customization of the provided <see cref="MemberValue"/>.
 /// </summary>
 /// <param name="context">The context.</param>
 /// <param name="memberValue">The member value.</param>
 /// <returns>The final <see cref="MemberValue"/> that will be deserialized.</returns>
 public virtual void DeserializeMember(ISerializationContext context, MemberValue memberValue)
 {
 }
 /// <summary>
 /// Determines whether the specified member value is a root dictionary.
 /// </summary>
 /// <param name="context">The context.</param>
 /// <param name="memberValue">The member value.</param>
 /// <returns><c>true</c> if the specified member value is a root dictionary; otherwise, <c>false</c>.</returns>
 protected virtual bool IsRootDictionary(ISerializationContext <TSerializationContext> context, MemberValue memberValue)
 {
     return(IsRootObject(context, memberValue, x => ShouldSerializeAsDictionary(x)));
 }