diff options
author | JamesNK <james@newtonking.com> | 2010-11-25 11:17:22 +0300 |
---|---|---|
committer | JamesNK <james@newtonking.com> | 2010-11-25 11:17:22 +0300 |
commit | 2eb0d3bf48f1fc675de46ee94911a71ccd62c66f (patch) | |
tree | 9adaddadf242ff44b0695283207e6c433fc5f672 /Src/Newtonsoft.Json | |
parent | efc2310a3dbcfbd6820dd57ad62ffa473258f5bc (diff) |
-Added XmlSerializer style Specified property support
Diffstat (limited to 'Src/Newtonsoft.Json')
6 files changed, 60 insertions, 10 deletions
diff --git a/Src/Newtonsoft.Json/Schema/JsonSchemaGenerator.cs b/Src/Newtonsoft.Json/Schema/JsonSchemaGenerator.cs index 1e6b60b..f906ebb 100644 --- a/Src/Newtonsoft.Json/Schema/JsonSchemaGenerator.cs +++ b/Src/Newtonsoft.Json/Schema/JsonSchemaGenerator.cs @@ -361,7 +361,8 @@ namespace Newtonsoft.Json.Schema {
bool optional = property.NullValueHandling == NullValueHandling.Ignore ||
property.DefaultValueHandling == DefaultValueHandling.Ignore ||
- property.ShouldSerialize != null;
+ property.ShouldSerialize != null ||
+ property.GetIsSpecified != null;
JsonSchema propertySchema = GenerateInternal(property.PropertyType, property.Required, optional);
diff --git a/Src/Newtonsoft.Json/Serialization/DefaultContractResolver.cs b/Src/Newtonsoft.Json/Serialization/DefaultContractResolver.cs index edc91df..2632593 100644 --- a/Src/Newtonsoft.Json/Serialization/DefaultContractResolver.cs +++ b/Src/Newtonsoft.Json/Serialization/DefaultContractResolver.cs @@ -35,6 +35,7 @@ using System.Linq; using System.Reflection;
using System.Runtime.Serialization;
using System.Security.Permissions;
+using System.Xml.Serialization;
using Newtonsoft.Json.Converters;
using Newtonsoft.Json.Utilities;
using Newtonsoft.Json.Linq;
@@ -717,6 +718,8 @@ namespace Newtonsoft.Json.Serialization property.ShouldSerialize = CreateShouldSerializeTest(member);
+ SetIsSpecifiedActions(property, member);
+
return property;
}
@@ -733,6 +736,25 @@ namespace Newtonsoft.Json.Serialization return o => (bool) shouldSerializeCall(o);
}
+ private void SetIsSpecifiedActions(JsonProperty property, MemberInfo member)
+ {
+ MemberInfo specifiedMember = member.DeclaringType.GetProperty(member.Name + JsonTypeReflector.SpecifiedPostfix);
+ if (specifiedMember == null)
+ specifiedMember = member.DeclaringType.GetField(member.Name + JsonTypeReflector.SpecifiedPostfix);
+
+ if (specifiedMember == null || ReflectionUtils.GetMemberUnderlyingType(specifiedMember) != typeof(bool)
+ || (ReflectionUtils.GetAttribute<XmlIgnoreAttribute>(specifiedMember) != null
+ && ReflectionUtils.GetAttribute<JsonIgnoreAttribute>(specifiedMember) != null))
+ {
+ return;
+ }
+
+ Func<object, object> specifiedPropertyGet = JsonTypeReflector.ReflectionDelegateFactory.CreateGet<object>(specifiedMember);
+
+ property.GetIsSpecified = o => (bool)specifiedPropertyGet(o);
+ property.SetIsSpecified = JsonTypeReflector.ReflectionDelegateFactory.CreateSet<object>(specifiedMember);
+ }
+
/// <summary>
/// Resolves the name of the property.
/// </summary>
diff --git a/Src/Newtonsoft.Json/Serialization/JsonProperty.cs b/Src/Newtonsoft.Json/Serialization/JsonProperty.cs index 13d721c..0b2512e 100644 --- a/Src/Newtonsoft.Json/Serialization/JsonProperty.cs +++ b/Src/Newtonsoft.Json/Serialization/JsonProperty.cs @@ -138,6 +138,18 @@ namespace Newtonsoft.Json.Serialization public Predicate<object> ShouldSerialize { get; set; }
/// <summary>
+ /// Gets or sets a predicate used to determine whether the property should be serialized.
+ /// </summary>
+ /// <value>A predicate used to determine whether the property should be serialized.</value>
+ public Predicate<object> GetIsSpecified { get; set; }
+
+ /// <summary>
+ /// Gets or sets an action used to set whether the property has been deserialized.
+ /// </summary>
+ /// <value>An action used to set whether the property has been deserialized.</value>
+ public Action<object, object> SetIsSpecified { get; set; }
+
+ /// <summary>
/// Returns a <see cref="String"/> that represents this instance.
/// </summary>
/// <returns>
diff --git a/Src/Newtonsoft.Json/Serialization/JsonSerializerInternalReader.cs b/Src/Newtonsoft.Json/Serialization/JsonSerializerInternalReader.cs index ca80b5d..8ca3954 100644 --- a/Src/Newtonsoft.Json/Serialization/JsonSerializerInternalReader.cs +++ b/Src/Newtonsoft.Json/Serialization/JsonSerializerInternalReader.cs @@ -552,7 +552,12 @@ namespace Newtonsoft.Json.Serialization // this could happen because of a JsonConverter against the type
if ((!useExistingValue || value != currentValue)
&& ShouldSetPropertyValue(property, value))
+ {
property.ValueProvider.SetValue(target, value);
+
+ if (property.SetIsSpecified != null)
+ property.SetIsSpecified(target, true);
+ }
}
private bool ShouldSetPropertyValue(JsonProperty property, object value)
diff --git a/Src/Newtonsoft.Json/Serialization/JsonSerializerInternalWriter.cs b/Src/Newtonsoft.Json/Serialization/JsonSerializerInternalWriter.cs index 526d94b..5b0e75d 100644 --- a/Src/Newtonsoft.Json/Serialization/JsonSerializerInternalWriter.cs +++ b/Src/Newtonsoft.Json/Serialization/JsonSerializerInternalWriter.cs @@ -57,7 +57,8 @@ namespace Newtonsoft.Json.Serialization }
}
- public JsonSerializerInternalWriter(JsonSerializer serializer) : base(serializer)
+ public JsonSerializerInternalWriter(JsonSerializer serializer)
+ : base(serializer)
{
}
@@ -109,7 +110,7 @@ namespace Newtonsoft.Json.Serialization }
else if (valueContract is JsonStringContract)
{
- SerializeString(writer, value, (JsonStringContract) valueContract);
+ SerializeString(writer, value, (JsonStringContract)valueContract);
}
else if (valueContract is JsonObjectContract)
{
@@ -117,12 +118,12 @@ namespace Newtonsoft.Json.Serialization }
else if (valueContract is JsonDictionaryContract)
{
- JsonDictionaryContract dictionaryContract = (JsonDictionaryContract) valueContract;
+ JsonDictionaryContract dictionaryContract = (JsonDictionaryContract)valueContract;
SerializeDictionary(writer, dictionaryContract.CreateWrapper(value), dictionaryContract, member, collectionValueContract);
}
else if (valueContract is JsonArrayContract)
{
- JsonArrayContract arrayContract = (JsonArrayContract) valueContract;
+ JsonArrayContract arrayContract = (JsonArrayContract)valueContract;
SerializeList(writer, arrayContract.CreateWrapper(value), arrayContract, member, collectionValueContract);
}
else if (valueContract is JsonLinqContract)
@@ -132,13 +133,13 @@ namespace Newtonsoft.Json.Serialization #if !SILVERLIGHT && !PocketPC
else if (valueContract is JsonISerializableContract)
{
- SerializeISerializable(writer, (ISerializable) value, (JsonISerializableContract) valueContract);
+ SerializeISerializable(writer, (ISerializable)value, (JsonISerializableContract)valueContract);
}
#endif
#if !(NET35 || NET20 || SILVERLIGHT)
else if (valueContract is JsonDynamicContract)
{
- SerializeDynamic(writer, (IDynamicMetaObjectProvider) value, (JsonDynamicContract) valueContract);
+ SerializeDynamic(writer, (IDynamicMetaObjectProvider)value, (JsonDynamicContract)valueContract);
}
#endif
}
@@ -242,9 +243,9 @@ namespace Newtonsoft.Json.Serialization // use the objectType's TypeConverter if it has one and can convert to a string
if (converter != null
#if !SILVERLIGHT
- && !(converter is ComponentConverter)
+ && !(converter is ComponentConverter)
#endif
- && converter.GetType() != typeof(TypeConverter))
+ && converter.GetType() != typeof(TypeConverter))
{
if (converter.CanConvertTo(typeof(string)))
{
@@ -311,7 +312,7 @@ namespace Newtonsoft.Json.Serialization {
try
{
- if (!property.Ignored && property.Readable && ShouldSerialize(property, value))
+ if (!property.Ignored && property.Readable && ShouldSerialize(property, value) && IsSpecified(property, value))
{
object memberValue = property.ValueProvider.GetValue(value);
JsonContract memberContract = GetContractSafe(memberValue);
@@ -610,5 +611,13 @@ namespace Newtonsoft.Json.Serialization return property.ShouldSerialize(target);
}
+
+ private bool IsSpecified(JsonProperty property, object target)
+ {
+ if (property.GetIsSpecified == null)
+ return true;
+
+ return property.GetIsSpecified(target);
+ }
}
}
\ No newline at end of file diff --git a/Src/Newtonsoft.Json/Serialization/JsonTypeReflector.cs b/Src/Newtonsoft.Json/Serialization/JsonTypeReflector.cs index e1d7261..b9f6493 100644 --- a/Src/Newtonsoft.Json/Serialization/JsonTypeReflector.cs +++ b/Src/Newtonsoft.Json/Serialization/JsonTypeReflector.cs @@ -49,6 +49,7 @@ namespace Newtonsoft.Json.Serialization public const string ArrayValuesPropertyName = "$values";
public const string ShouldSerializePrefix = "ShouldSerialize";
+ public const string SpecifiedPostfix = "Specified";
private static readonly ThreadSafeStore<ICustomAttributeProvider, Type> JsonConverterTypeCache = new ThreadSafeStore<ICustomAttributeProvider, Type>(GetJsonConverterTypeFromAttribute);
#if !SILVERLIGHT && !PocketPC && !NET20
|