/// <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; }
/// <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; }
/// <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); }
/// <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); } }
/// <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))); }