-Added ItemIsReference, ItemReferenceLoopHandling, ItemTypeNameHandling, ItemConverterType to JsonPropertyAttribute

This commit is contained in:
James Newton-King
2012-05-05 20:30:02 +12:00
parent 0e22f39e12
commit 2dfd0bc940
14 changed files with 1284 additions and 630 deletions
@@ -114,6 +114,35 @@ namespace Newtonsoft.Json.Tests.Converters
return node;
}
#if !NET20
[Test]
public void SerializeEmptyDocument()
{
XmlDocument doc = new XmlDocument();
doc.LoadXml("<root />");
string json = JsonConvert.SerializeXmlNode(doc, Formatting.Indented, true);
Assert.AreEqual("null", json);
doc = new XmlDocument();
doc.LoadXml("<root></root>");
json = JsonConvert.SerializeXmlNode(doc, Formatting.Indented, true);
Assert.AreEqual("null", json);
XDocument doc1 = XDocument.Parse("<root />");
json = JsonConvert.SerializeXNode(doc1, Formatting.Indented, true);
Assert.AreEqual("null", json);
doc1 = XDocument.Parse("<root></root>");
json = JsonConvert.SerializeXNode(doc1, Formatting.Indented, true);
Assert.AreEqual("null", json);
}
#endif
[Test]
public void DocumentSerializeIndented()
{
+17 -17
View File
@@ -712,27 +712,27 @@ namespace Newtonsoft.Json.Tests.Linq
""StockValue"": 22050.0
}", json);
}
}
public class DynamicDictionary : DynamicObject
public class DynamicDictionary : DynamicObject
{
private readonly IDictionary<string, object> _values = new Dictionary<string, object>();
public override IEnumerable<string> GetDynamicMemberNames()
{
private readonly IDictionary<string, object> _values = new Dictionary<string, object>();
return _values.Keys;
}
public override IEnumerable<string> GetDynamicMemberNames()
{
return _values.Keys;
}
public override bool TryGetMember(GetMemberBinder binder, out object result)
{
result = _values[binder.Name];
return true;
}
public override bool TryGetMember(GetMemberBinder binder, out object result)
{
result = _values[binder.Name];
return true;
}
public override bool TrySetMember(SetMemberBinder binder, object value)
{
_values[binder.Name] = value;
return true;
}
public override bool TrySetMember(SetMemberBinder binder, object value)
{
_values[binder.Name] = value;
return true;
}
}
}
@@ -72,5 +72,5 @@ using System.Security;
// by using the '*' as shown below:
[assembly: AssemblyVersion("4.5.0.0")]
#if !PocketPC
[assembly: AssemblyFileVersion("4.5.4.14902")]
[assembly: AssemblyFileVersion("4.5.4.14905")]
#endif
@@ -751,6 +751,33 @@ namespace Newtonsoft.Json.Tests.Schema
}
}", json);
}
[Test]
public void GenerateForNullableInt32()
{
JsonSchemaGenerator jsonSchemaGenerator = new JsonSchemaGenerator();
JsonSchema jsonSchema = jsonSchemaGenerator.Generate(typeof(NullableInt32TestClass));
string json = jsonSchema.ToString();
Assert.AreEqual(@"{
""type"": ""object"",
""properties"": {
""Value"": {
""required"": true,
""type"": [
""integer"",
""null""
]
}
}
}", json);
}
}
public class NullableInt32TestClass
{
public int? Value { get; set; }
}
public class DMDSLBase
File diff suppressed because it is too large Load Diff
@@ -1006,6 +1006,74 @@ namespace Newtonsoft.Json.Tests.Serialization
Assert.IsTrue(ReferenceEquals(referenceObject.Component1, referenceObject.Component2));
}
[Test]
public void PropertyItemIsReferenceObject()
{
TestComponentSimple c1 = new TestComponentSimple();
PropertyItemIsReferenceObject o1 = new PropertyItemIsReferenceObject
{
Data = new PropertyItemIsReferenceBody
{
Prop1 = c1,
Prop2 = c1,
Data = new List<TestComponentSimple>
{
c1
}
}
};
string json = JsonConvert.SerializeObject(o1, Formatting.Indented);
Assert.AreEqual(@"{
""Data"": {
""Prop1"": {
""$id"": ""1"",
""MyProperty"": 0
},
""Prop2"": {
""$ref"": ""1""
},
""Data"": {
""$id"": ""2"",
""$values"": [
{
""MyProperty"": 0
}
]
}
}
}", json);
PropertyItemIsReferenceObject o2 = JsonConvert.DeserializeObject<PropertyItemIsReferenceObject>(json);
TestComponentSimple c2 = o2.Data.Prop1;
TestComponentSimple c3 = o2.Data.Prop2;
TestComponentSimple c4 = o2.Data.Data[0];
Assert.IsTrue(ReferenceEquals(c2, c3));
Assert.IsFalse(ReferenceEquals(c2, c4));
}
}
public class PropertyItemIsReferenceBody
{
public TestComponentSimple Prop1 { get; set; }
public TestComponentSimple Prop2 { get; set; }
public IList<TestComponentSimple> Data { get; set; }
}
public class PropertyItemIsReferenceObject
{
[JsonProperty(ItemIsReference = true)]
public PropertyItemIsReferenceBody Data { get; set; }
}
public class PropertyItemIsReferenceList
{
[JsonProperty(ItemIsReference = true)]
public IList<IList<object>> Data { get; set; }
}
[JsonArray(ItemIsReference = true)]
@@ -112,6 +112,62 @@ namespace Newtonsoft.Json.Tests.Serialization
});
Assert.AreEqual("{}", json);
}
[Test]
public void SerializePropertyItemReferenceLoopHandling()
{
PropertyItemReferenceLoopHandling c = new PropertyItemReferenceLoopHandling();
c.Text = "Text!";
c.SetData(new List<PropertyItemReferenceLoopHandling> { c });
string json = JsonConvert.SerializeObject(c, Formatting.Indented);
Assert.AreEqual(@"{
""Text"": ""Text!"",
""Data"": [
{
""Text"": ""Text!"",
""Data"": [
{
""Text"": ""Text!"",
""Data"": [
{
""Text"": ""Text!"",
""Data"": null
}
]
}
]
}
]
}", json);
}
}
public class PropertyItemReferenceLoopHandling
{
private IList<PropertyItemReferenceLoopHandling> _data;
private int _accessCount;
public string Text { get; set; }
[JsonProperty(ItemReferenceLoopHandling = ReferenceLoopHandling.Serialize)]
public IList<PropertyItemReferenceLoopHandling> Data
{
get
{
if (_accessCount >= 3)
return null;
_accessCount++;
return new List<PropertyItemReferenceLoopHandling>(_data);
}
}
public void SetData(IList<PropertyItemReferenceLoopHandling> data)
{
_data = data;
}
}
[JsonArray(ItemReferenceLoopHandling = ReferenceLoopHandling.Ignore)]
File diff suppressed because it is too large Load Diff
+26 -5
View File
@@ -43,12 +43,15 @@ namespace Newtonsoft.Json
internal bool? _isReference;
internal int? _order;
internal Required? _required;
internal bool? _itemIsReference;
internal ReferenceLoopHandling? _itemReferenceLoopHandling;
internal TypeNameHandling? _itemTypeNameHandling;
///// <summary>
///// Gets the collection's items converter.
///// </summary>
///// <value>The collection's items converter.</value>
//public Type ItemConverterType { get; set; }
/// <summary>
/// Gets the collection's items converter.
/// </summary>
/// <value>The collection's items converter.</value>
public Type ItemConverterType { get; set; }
/// <summary>
/// Gets or sets the null value handling used when serializing this property.
@@ -138,6 +141,24 @@ namespace Newtonsoft.Json
/// <value>The name of the property.</value>
public string PropertyName { get; set; }
public ReferenceLoopHandling ItemReferenceLoopHandling
{
get { return _itemReferenceLoopHandling ?? default(ReferenceLoopHandling); }
set { _itemReferenceLoopHandling = value; }
}
public TypeNameHandling ItemTypeNameHandling
{
get { return _itemTypeNameHandling ?? default(TypeNameHandling); }
set { _itemTypeNameHandling = value; }
}
public bool ItemIsReference
{
get { return _itemIsReference ?? default(bool); }
set { _itemIsReference = value; }
}
/// <summary>
/// Initializes a new instance of the <see cref="JsonPropertyAttribute"/> class.
/// </summary>
@@ -90,7 +90,7 @@ using System.Security;
// by using the '*' as shown below:
[assembly: AssemblyVersion("4.5.0.0")]
#if !PocketPC
[assembly: AssemblyFileVersion("4.5.4.14902")]
[assembly: AssemblyFileVersion("4.5.4.14905")]
#endif
[assembly: CLSCompliant(true)]
@@ -961,7 +961,7 @@ namespace Newtonsoft.Json.Serialization
bool hasJsonIgnoreAttribute = JsonTypeReflector.GetAttribute<JsonIgnoreAttribute>(attributeProvider) != null
#if !(SILVERLIGHT || NETFX_CORE || PORTABLE)
|| JsonTypeReflector.GetAttribute<NonSerializedAttribute>(attributeProvider) != null
|| JsonTypeReflector.GetAttribute<NonSerializedAttribute>(attributeProvider) != null
#endif
;
@@ -997,6 +997,14 @@ namespace Newtonsoft.Json.Serialization
property.TypeNameHandling = (propertyAttribute != null) ? propertyAttribute._typeNameHandling : null;
property.IsReference = (propertyAttribute != null) ? propertyAttribute._isReference : null;
property.ItemIsReference = (propertyAttribute != null) ? propertyAttribute._itemIsReference : null;
property.ItemConverter =
(propertyAttribute != null && propertyAttribute.ItemConverterType != null)
? JsonConverterAttribute.CreateJsonConverterInstance(propertyAttribute.ItemConverterType)
: null;
property.ItemReferenceLoopHandling = (propertyAttribute != null) ? propertyAttribute._itemReferenceLoopHandling : null;
property.ItemTypeNameHandling = (propertyAttribute != null) ? propertyAttribute._itemTypeNameHandling : null;
allowNonPublicAccess = false;
if ((DefaultMembersSearchFlags & BindingFlags.NonPublic) == BindingFlags.NonPublic)
allowNonPublicAccess = true;
@@ -35,6 +35,8 @@ namespace Newtonsoft.Json.Serialization
/// </summary>
public class JsonProperty
{
internal Required? _required;
// use to cache contract during deserialization
internal JsonContract PropertyContract { get; set; }
@@ -111,8 +113,6 @@ namespace Newtonsoft.Json.Serialization
/// <value>The default value.</value>
public object DefaultValue { get; set; }
internal Required? _required;
/// <summary>
/// Gets a value indicating whether this <see cref="JsonProperty"/> is required.
/// </summary>
@@ -189,5 +189,10 @@ namespace Newtonsoft.Json.Serialization
{
return PropertyName;
}
public JsonConverter ItemConverter { get; set; }
public bool? ItemIsReference { get; set; }
public TypeNameHandling? ItemTypeNameHandling { get; set; }
public ReferenceLoopHandling? ItemReferenceLoopHandling { get; set; }
}
}
@@ -69,7 +69,7 @@ namespace Newtonsoft.Json.Serialization
if (reader.TokenType == JsonToken.StartArray)
{
if (contract.ContractType == JsonContractType.Array)
PopulateList(CollectionUtils.CreateCollectionWrapper(target), reader, null, (JsonArrayContract) contract);
PopulateList(CollectionUtils.CreateCollectionWrapper(target), reader, null, (JsonArrayContract) contract, null);
else
throw JsonSerializationException.Create(reader, "Cannot populate JSON array onto type '{0}'.".FormatWith(CultureInfo.InvariantCulture, objectType));
}
@@ -86,9 +86,9 @@ namespace Newtonsoft.Json.Serialization
}
if (contract.ContractType == JsonContractType.Dictionary)
PopulateDictionary(CollectionUtils.CreateDictionaryWrapper(target), reader, (JsonDictionaryContract) contract, id);
PopulateDictionary(CollectionUtils.CreateDictionaryWrapper(target), reader, (JsonDictionaryContract) contract, null, null, id);
else if (contract.ContractType == JsonContractType.Object)
PopulateObject(target, reader, (JsonObjectContract) contract, id);
PopulateObject(target, reader, (JsonObjectContract) contract, null, null, id);
else
throw JsonSerializationException.Create(reader, "Cannot populate JSON object onto type '{0}'.".FormatWith(CultureInfo.InvariantCulture, objectType));
}
@@ -115,7 +115,7 @@ namespace Newtonsoft.Json.Serialization
try
{
JsonConverter converter = GetConverter(contract, null, null);
JsonConverter converter = GetConverter(contract, null, null, null);
if (reader.TokenType == JsonToken.None && !ReadForType(reader, contract, converter != null, false))
{
@@ -125,7 +125,7 @@ namespace Newtonsoft.Json.Serialization
return null;
}
return CreateValueNonProperty(reader, objectType, contract, converter, null);
return CreateValueNonProperty(reader, objectType, contract, converter, null, null);
}
catch (Exception ex)
{
@@ -201,7 +201,7 @@ namespace Newtonsoft.Json.Serialization
return token;
}
private object CreateValueProperty(JsonReader reader, JsonProperty property, JsonConverter propertyConverter, JsonContainerContract containerContract, object target, bool gottenCurrentValue, object currentValue)
private object CreateValueProperty(JsonReader reader, JsonProperty property, JsonConverter propertyConverter, JsonContainerContract containerContract, JsonProperty containerProperty, object target, bool gottenCurrentValue, object currentValue)
{
JsonContract contract;
JsonConverter converter;
@@ -219,7 +219,7 @@ namespace Newtonsoft.Json.Serialization
contract = GetContractSafe(currentValue.GetType());
if (contract != property.PropertyContract)
converter = GetConverter(contract, property.MemberConverter, containerContract);
converter = GetConverter(contract, property.MemberConverter, containerContract, containerProperty);
else
converter = propertyConverter;
}
@@ -234,18 +234,18 @@ namespace Newtonsoft.Json.Serialization
return converter.ReadJson(reader, objectType, currentValue, GetInternalSerializer());
}
return CreateValueInternal(reader, objectType, contract, property, containerContract, currentValue);
return CreateValueInternal(reader, objectType, contract, property, containerContract, containerProperty, currentValue);
}
private object CreateValueNonProperty(JsonReader reader, Type objectType, JsonContract contract, JsonConverter converter, JsonContainerContract containerContract)
private object CreateValueNonProperty(JsonReader reader, Type objectType, JsonContract contract, JsonConverter converter, JsonContainerContract containerContract, JsonProperty containerProperty)
{
if (converter != null && converter.CanRead)
return converter.ReadJson(reader, objectType, null, GetInternalSerializer());
return CreateValueInternal(reader, objectType, contract, null, containerContract, null);
return CreateValueInternal(reader, objectType, contract, null, containerContract, containerProperty, null);
}
private object CreateValueInternal(JsonReader reader, Type objectType, JsonContract contract, JsonProperty member, JsonContainerContract containerContract, object existingValue)
private object CreateValueInternal(JsonReader reader, Type objectType, JsonContract contract, JsonProperty member, JsonContainerContract containerContract, JsonProperty containerMember, object existingValue)
{
if (contract != null && contract.ContractType == JsonContractType.Linq)
return CreateJToken(reader, contract);
@@ -257,9 +257,9 @@ namespace Newtonsoft.Json.Serialization
// populate a typed object or generic dictionary/array
// depending upon whether an objectType was supplied
case JsonToken.StartObject:
return CreateObject(reader, objectType, contract, member, containerContract, existingValue);
return CreateObject(reader, objectType, contract, member, containerContract, containerMember, existingValue);
case JsonToken.StartArray:
return CreateList(reader, objectType, contract, member, existingValue, null);
return CreateList(reader, objectType, contract, member, containerMember, existingValue, null);
case JsonToken.Integer:
case JsonToken.Float:
case JsonToken.Boolean:
@@ -268,7 +268,7 @@ namespace Newtonsoft.Json.Serialization
return EnsureType(reader, reader.Value, CultureInfo.InvariantCulture, contract, objectType);
case JsonToken.String:
// convert empty string to null automatically for nullable types
if (string.IsNullOrEmpty((string)reader.Value) && objectType != typeof(string) && objectType != typeof(object) && contract.IsNullable)
if (string.IsNullOrEmpty((string)reader.Value) && objectType != typeof(string) && objectType != typeof(object) && contract != null && contract.IsNullable)
return null;
// string that needs to be returned as a byte array should be base 64 decoded
@@ -301,7 +301,7 @@ namespace Newtonsoft.Json.Serialization
throw JsonSerializationException.Create(reader, "Unexpected end when deserializing object.");
}
private JsonConverter GetConverter(JsonContract contract, JsonConverter memberConverter, JsonContainerContract containerContract)
private JsonConverter GetConverter(JsonContract contract, JsonConverter memberConverter, JsonContainerContract containerContract, JsonProperty containerProperty)
{
JsonConverter converter = null;
if (memberConverter != null)
@@ -309,6 +309,10 @@ namespace Newtonsoft.Json.Serialization
// member attribute converter
converter = memberConverter;
}
else if (containerProperty != null && containerProperty.ItemConverter != null)
{
converter = containerProperty.ItemConverter;
}
else if (containerContract != null && containerContract.ItemConverter != null)
{
converter = containerContract.ItemConverter;
@@ -329,7 +333,7 @@ namespace Newtonsoft.Json.Serialization
return converter;
}
private object CreateObject(JsonReader reader, Type objectType, JsonContract contract, JsonProperty member, JsonContainerContract containerContract, object existingValue)
private object CreateObject(JsonReader reader, Type objectType, JsonContract contract, JsonProperty member, JsonContainerContract containerContract, JsonProperty containerMember, object existingValue)
{
CheckedRead(reader);
@@ -378,6 +382,7 @@ namespace Newtonsoft.Json.Serialization
TypeNameHandling resolvedTypeNameHandling = ((member != null) ? member.TypeNameHandling : null)
?? ((containerContract != null) ? containerContract.ItemTypeNameHandling : null)
?? ((containerMember != null) ? containerMember.ItemTypeNameHandling : null)
?? Serializer.TypeNameHandling;
if (resolvedTypeNameHandling != TypeNameHandling.None)
@@ -399,7 +404,11 @@ namespace Newtonsoft.Json.Serialization
if (specifiedType == null)
throw JsonSerializationException.Create(reader, "Type specified in JSON '{0}' was not resolved.".FormatWith(CultureInfo.InvariantCulture, qualifiedTypeName));
if (objectType != null && !objectType.IsAssignableFrom(specifiedType))
if (objectType != null
#if !(NET35 || NET20 || WINDOWS_PHONE || PORTABLE)
&& objectType != typeof(IDynamicMetaObjectProvider)
#endif
&& !objectType.IsAssignableFrom(specifiedType))
throw JsonSerializationException.Create(reader, "Type specified in JSON '{0}' is not compatible with '{1}'.".FormatWith(CultureInfo.InvariantCulture, specifiedType.AssemblyQualifiedName, objectType.AssemblyQualifiedName));
objectType = specifiedType;
@@ -422,7 +431,7 @@ namespace Newtonsoft.Json.Serialization
else if (string.Equals(propertyName, JsonTypeReflector.ArrayValuesPropertyName, StringComparison.Ordinal))
{
CheckedRead(reader);
object list = CreateList(reader, objectType, contract, member, existingValue, id);
object list = CreateList(reader, objectType, contract, member, containerMember, existingValue, id);
CheckedRead(reader);
return list;
}
@@ -446,16 +455,16 @@ namespace Newtonsoft.Json.Serialization
case JsonContractType.Object:
JsonObjectContract objectContract = (JsonObjectContract) contract;
if (existingValue == null)
return CreateAndPopulateObject(reader, objectContract, id);
return CreateAndPopulateObject(reader, objectContract, member, containerMember, id);
return PopulateObject(existingValue, reader, objectContract, id);
return PopulateObject(existingValue, reader, objectContract, member, containerMember, id);
case JsonContractType.Primitive:
JsonPrimitiveContract primitiveContract = (JsonPrimitiveContract) contract;
// if the content is inside $value then read past it
if (reader.TokenType == JsonToken.PropertyName && string.Equals(reader.Value.ToString(), JsonTypeReflector.ValuePropertyName, StringComparison.Ordinal))
{
CheckedRead(reader);
object value = CreateValueInternal(reader, objectType, primitiveContract, member, null, existingValue);
object value = CreateValueInternal(reader, objectType, primitiveContract, member, null, null, existingValue);
CheckedRead(reader);
return value;
@@ -464,13 +473,13 @@ namespace Newtonsoft.Json.Serialization
case JsonContractType.Dictionary:
JsonDictionaryContract dictionaryContract = (JsonDictionaryContract) contract;
if (existingValue == null)
return CreateAndPopulateDictionary(reader, dictionaryContract, id);
return CreateAndPopulateDictionary(reader, dictionaryContract, member, containerMember, id);
return PopulateDictionary(dictionaryContract.CreateWrapper(existingValue), reader, dictionaryContract, id);
return PopulateDictionary(dictionaryContract.CreateWrapper(existingValue), reader, dictionaryContract, member, containerMember, id);
#if !(NET35 || NET20 || WINDOWS_PHONE || PORTABLE)
case JsonContractType.Dynamic:
JsonDynamicContract dynamicContract = (JsonDynamicContract) contract;
return CreateDynamic(reader, dynamicContract, id);
return CreateDynamic(reader, dynamicContract, member, id);
#endif
#if !(SILVERLIGHT || NETFX_CORE || PORTABLE)
case JsonContractType.Serializable:
@@ -504,7 +513,7 @@ To force JSON arrays to deserialize add the JsonArrayAttribute to the type.".For
throw JsonSerializationException.Create(reader, "Unexpected end when deserializing object.");
}
private object CreateList(JsonReader reader, Type objectType, JsonContract contract, JsonProperty member, object existingValue, string reference)
private object CreateList(JsonReader reader, Type objectType, JsonContract contract, JsonProperty member, JsonProperty containerProperty, object existingValue, string reference)
{
object value;
if (HasDefinedType(objectType))
@@ -512,9 +521,9 @@ To force JSON arrays to deserialize add the JsonArrayAttribute to the type.".For
JsonArrayContract arrayContract = EnsureArrayContract(reader, objectType, contract);
if (existingValue == null)
value = CreateAndPopulateList(reader, reference, arrayContract);
value = CreateAndPopulateList(reader, reference, arrayContract, member, containerProperty);
else
value = PopulateList(arrayContract.CreateWrapper(existingValue), reader, reference, arrayContract);
value = PopulateList(arrayContract.CreateWrapper(existingValue), reader, reference, arrayContract, member);
}
else
{
@@ -583,7 +592,7 @@ To force JSON arrays to deserialize add the JsonArrayAttribute to the type.".For
return value.ToString();
}
private void SetPropertyValue(JsonProperty property, JsonConverter propertyConverter, JsonContainerContract containerContract, JsonReader reader, object target)
private void SetPropertyValue(JsonProperty property, JsonConverter propertyConverter, JsonContainerContract containerContract, JsonProperty containerProperty, JsonReader reader, object target)
{
if (property.Ignored)
{
@@ -634,7 +643,7 @@ To force JSON arrays to deserialize add the JsonArrayAttribute to the type.".For
}
object existingValue = (useExistingValue) ? currentValue : null;
object value = CreateValueProperty(reader, property, propertyConverter, containerContract, target, gottenCurrentValue, existingValue);
object value = CreateValueProperty(reader, property, propertyConverter, containerContract, containerProperty, target, gottenCurrentValue, existingValue);
// always set the value if useExistingValue is false,
// otherwise also set it if CreateValue returns a new value compared to the currentValue
@@ -669,7 +678,7 @@ To force JSON arrays to deserialize add the JsonArrayAttribute to the type.".For
return true;
}
private object CreateAndPopulateDictionary(JsonReader reader, JsonDictionaryContract contract, string id)
private object CreateAndPopulateDictionary(JsonReader reader, JsonDictionaryContract contract, JsonProperty member, JsonProperty containerProperty, string id)
{
object dictionary;
@@ -681,12 +690,12 @@ To force JSON arrays to deserialize add the JsonArrayAttribute to the type.".For
IWrappedDictionary dictionaryWrapper = contract.CreateWrapper(dictionary);
PopulateDictionary(dictionaryWrapper, reader, contract, id);
PopulateDictionary(dictionaryWrapper, reader, contract, member, containerProperty, id);
return dictionaryWrapper.UnderlyingDictionary;
}
private object PopulateDictionary(IWrappedDictionary dictionary, JsonReader reader, JsonDictionaryContract contract, string id)
private object PopulateDictionary(IWrappedDictionary dictionary, JsonReader reader, JsonDictionaryContract contract, JsonProperty member, JsonProperty containerProperty, string id)
{
if (id != null)
Serializer.ReferenceResolver.AddReference(this, id, dictionary.UnderlyingDictionary);
@@ -718,12 +727,12 @@ To force JSON arrays to deserialize add the JsonArrayAttribute to the type.".For
if (contract.ItemContract == null)
contract.ItemContract = GetContractSafe(contract.DictionaryValueType);
JsonConverter dictionaryValueConverter = contract.ItemConverter ?? GetConverter(contract.ItemContract, null, contract);
JsonConverter dictionaryValueConverter = contract.ItemConverter ?? GetConverter(contract.ItemContract, null, contract, containerProperty);
if (!ReadForType(reader, contract.ItemContract, dictionaryValueConverter != null, false))
throw JsonSerializationException.Create(reader, "Unexpected end when deserializing object.");
dictionary[keyValue] = CreateValueNonProperty(reader, contract.DictionaryValueType, contract.ItemContract, dictionaryValueConverter, contract);
dictionary[keyValue] = CreateValueNonProperty(reader, contract.DictionaryValueType, contract.ItemContract, dictionaryValueConverter, contract, member);
}
catch (Exception ex)
{
@@ -747,7 +756,7 @@ To force JSON arrays to deserialize add the JsonArrayAttribute to the type.".For
throw JsonSerializationException.Create(reader, "Unexpected end when deserializing object.");
}
private object CreateAndPopulateList(JsonReader reader, string reference, JsonArrayContract contract)
private object CreateAndPopulateList(JsonReader reader, string reference, JsonArrayContract contract, JsonProperty member, JsonProperty containerProperty)
{
return CollectionUtils.CreateAndPopulateList(contract.CreatedType, (l, isTemporaryListReference) =>
{
@@ -761,11 +770,11 @@ To force JSON arrays to deserialize add the JsonArrayAttribute to the type.".For
if (contract.OnError != null && isTemporaryListReference)
throw JsonSerializationException.Create(reader, "Cannot call OnError on an array or readonly list: {0}.".FormatWith(CultureInfo.InvariantCulture, contract.UnderlyingType));
PopulateList(contract.CreateWrapper(l), reader, reference, contract);
PopulateList(contract.CreateWrapper(l), reader, reference, contract, member);
});
}
private object PopulateList(IWrappedCollection wrappedList, JsonReader reader, string reference, JsonArrayContract contract)
private object PopulateList(IWrappedCollection wrappedList, JsonReader reader, string reference, JsonArrayContract contract, JsonProperty containerProperty)
{
object list = wrappedList.UnderlyingCollection;
@@ -785,7 +794,7 @@ To force JSON arrays to deserialize add the JsonArrayAttribute to the type.".For
int index = 0;
JsonContract collectionItemContract = GetContractSafe(contract.CollectionItemType);
JsonConverter collectionItemConverter = GetConverter(collectionItemContract, null, contract);
JsonConverter collectionItemConverter = GetConverter(collectionItemContract, null, contract, containerProperty);
while (true)
{
@@ -802,7 +811,7 @@ To force JSON arrays to deserialize add the JsonArrayAttribute to the type.".For
case JsonToken.Comment:
break;
default:
object value = CreateValueNonProperty(reader, contract.CollectionItemType, collectionItemContract, collectionItemConverter, contract);
object value = CreateValueNonProperty(reader, contract.CollectionItemType, collectionItemContract, collectionItemConverter, contract, containerProperty);
wrappedList.Add(value);
break;
@@ -881,7 +890,7 @@ To fix this error either change the environment to be fully trusted, change the
#endif
#if !(NET35 || NET20 || WINDOWS_PHONE || PORTABLE)
private object CreateDynamic(JsonReader reader, JsonDynamicContract contract, string id)
private object CreateDynamic(JsonReader reader, JsonDynamicContract contract, JsonProperty member, string id)
{
IDynamicMetaObjectProvider newObject = null;
@@ -922,18 +931,18 @@ To fix this error either change the environment to be fully trusted, change the
if (property.PropertyContract == null)
property.PropertyContract = GetContractSafe(property.PropertyType);
JsonConverter propertyConverter = GetConverter(property.PropertyContract, property.MemberConverter, null);
JsonConverter propertyConverter = GetConverter(property.PropertyContract, property.MemberConverter, null, null);
SetPropertyValue(property, propertyConverter, null, reader, newObject);
SetPropertyValue(property, propertyConverter, null, member, reader, newObject);
}
else
{
Type t = (JsonReader.IsPrimitiveToken(reader.TokenType)) ? reader.ValueType : typeof (IDynamicMetaObjectProvider);
JsonContract dynamicMemberContract = GetContractSafe(t);
JsonConverter dynamicMemberConverter = GetConverter(dynamicMemberContract, null, null);
JsonConverter dynamicMemberConverter = GetConverter(dynamicMemberContract, null, null, member);
object value = CreateValueNonProperty(reader, t, dynamicMemberContract, dynamicMemberConverter, null);
object value = CreateValueNonProperty(reader, t, dynamicMemberContract, dynamicMemberConverter, null, member);
newObject.TrySetMember(memberName, value);
}
@@ -960,7 +969,7 @@ To fix this error either change the environment to be fully trusted, change the
}
#endif
private object CreateAndPopulateObject(JsonReader reader, JsonObjectContract contract, string id)
private object CreateAndPopulateObject(JsonReader reader, JsonObjectContract contract, JsonProperty member, JsonProperty containerProperty, string id)
{
object newObject = null;
@@ -970,7 +979,7 @@ To fix this error either change the environment to be fully trusted, change the
if (contract.OverrideConstructor != null)
{
if (contract.OverrideConstructor.GetParameters().Length > 0)
return CreateObjectFromNonDefaultConstructor(reader, contract, contract.OverrideConstructor, id);
return CreateObjectFromNonDefaultConstructor(reader, contract, containerProperty, contract.OverrideConstructor, id);
newObject = contract.OverrideConstructor.Invoke(null);
}
@@ -985,23 +994,23 @@ To fix this error either change the environment to be fully trusted, change the
}
else if (contract.ParametrizedConstructor != null)
{
return CreateObjectFromNonDefaultConstructor(reader, contract, contract.ParametrizedConstructor, id);
return CreateObjectFromNonDefaultConstructor(reader, contract, containerProperty, contract.ParametrizedConstructor, id);
}
if (newObject == null)
throw JsonSerializationException.Create(reader, "Unable to find a constructor to use for type {0}. A class should either have a default constructor, one constructor with arguments or a constructor marked with the JsonConstructor attribute.".FormatWith(CultureInfo.InvariantCulture, contract.UnderlyingType));
PopulateObject(newObject, reader, contract, id);
PopulateObject(newObject, reader, contract, member, containerProperty, id);
return newObject;
}
private object CreateObjectFromNonDefaultConstructor(JsonReader reader, JsonObjectContract contract, ConstructorInfo constructorInfo, string id)
private object CreateObjectFromNonDefaultConstructor(JsonReader reader, JsonObjectContract contract, JsonProperty containerProperty, ConstructorInfo constructorInfo, string id)
{
ValidationUtils.ArgumentNotNull(constructorInfo, "constructorInfo");
Type objectType = contract.UnderlyingType;
IDictionary<JsonProperty, object> propertyValues = ResolvePropertyAndConstructorValues(contract, reader, objectType);
IDictionary<JsonProperty, object> propertyValues = ResolvePropertyAndConstructorValues(contract, containerProperty, reader, objectType);
IDictionary<ParameterInfo, object> constructorParameters = constructorInfo.GetParameters().ToDictionary(p => p, p => (object) null);
IDictionary<JsonProperty, object> remainingPropertyValues = new Dictionary<JsonProperty, object>();
@@ -1039,7 +1048,7 @@ To fix this error either change the environment to be fully trusted, change the
if (propertyContract.ContractType == JsonContractType.Array)
{
JsonArrayContract propertyArrayContract = propertyContract as JsonArrayContract;
JsonArrayContract propertyArrayContract = (JsonArrayContract)propertyContract;
object createdObjectCollection = property.ValueProvider.GetValue(createdObject);
if (createdObjectCollection != null)
@@ -1055,7 +1064,7 @@ To fix this error either change the environment to be fully trusted, change the
}
else if (propertyContract.ContractType == JsonContractType.Dictionary)
{
JsonDictionaryContract jsonDictionaryContract = propertyContract as JsonDictionaryContract;
JsonDictionaryContract jsonDictionaryContract = (JsonDictionaryContract)propertyContract;
object createdObjectDictionary = property.ValueProvider.GetValue(createdObject);
if (createdObjectDictionary != null)
@@ -1076,7 +1085,7 @@ To fix this error either change the environment to be fully trusted, change the
return createdObject;
}
private IDictionary<JsonProperty, object> ResolvePropertyAndConstructorValues(JsonObjectContract contract, JsonReader reader, Type objectType)
private IDictionary<JsonProperty, object> ResolvePropertyAndConstructorValues(JsonObjectContract contract, JsonProperty containerProperty, JsonReader reader, Type objectType)
{
IDictionary<JsonProperty, object> propertyValues = new Dictionary<JsonProperty, object>();
bool exit = false;
@@ -1097,13 +1106,13 @@ To fix this error either change the environment to be fully trusted, change the
if (property.PropertyContract == null)
property.PropertyContract = GetContractSafe(property.PropertyType);
JsonConverter propertyConverter = GetConverter(property.PropertyContract, property.MemberConverter, contract);
JsonConverter propertyConverter = GetConverter(property.PropertyContract, property.MemberConverter, contract, containerProperty);
if (!ReadForType(reader, property.PropertyContract, propertyConverter != null, false))
throw JsonSerializationException.Create(reader, "Unexpected end when setting {0}'s value.".FormatWith(CultureInfo.InvariantCulture, memberName));
if (!property.Ignored)
propertyValues[property] = CreateValueProperty(reader, property, propertyConverter, contract, null, true, null);
propertyValues[property] = CreateValueProperty(reader, property, propertyConverter, contract, containerProperty, null, true, null);
else
reader.Skip();
}
@@ -1177,7 +1186,7 @@ To fix this error either change the environment to be fully trusted, change the
return (reader.TokenType != JsonToken.None);
}
private object PopulateObject(object newObject, JsonReader reader, JsonObjectContract contract, string id)
private object PopulateObject(object newObject, JsonReader reader, JsonObjectContract contract, JsonProperty member, JsonProperty containerProperty, string id)
{
contract.InvokeOnDeserializing(newObject, Serializer.Context);
@@ -1215,14 +1224,14 @@ To fix this error either change the environment to be fully trusted, change the
if (property.PropertyContract == null)
property.PropertyContract = GetContractSafe(property.PropertyType);
JsonConverter propertyConverter = GetConverter(property.PropertyContract, property.MemberConverter, contract);
JsonConverter propertyConverter = GetConverter(property.PropertyContract, property.MemberConverter, contract, member);
if (!ReadForType(reader, property.PropertyContract, propertyConverter != null, false))
throw JsonSerializationException.Create(reader, "Unexpected end when setting {0}'s value.".FormatWith(CultureInfo.InvariantCulture, memberName));
SetPropertyPresence(reader, property, propertiesPresence);
SetPropertyValue(property, propertyConverter, contract, reader, newObject);
SetPropertyValue(property, propertyConverter, contract, member, reader, newObject);
}
catch (Exception ex)
{
@@ -58,7 +58,7 @@ namespace Newtonsoft.Json.Serialization
if (jsonWriter == null)
throw new ArgumentNullException("jsonWriter");
SerializeValue(jsonWriter, value, GetContractSafe(value), null, null);
SerializeValue(jsonWriter, value, GetContractSafe(value), null, null, null);
}
private JsonSerializerProxy GetInternalSerializer()
@@ -77,11 +77,11 @@ namespace Newtonsoft.Json.Serialization
return Serializer.ContractResolver.ResolveContract(value.GetType());
}
private void SerializePrimitive(JsonWriter writer, object value, JsonPrimitiveContract contract, JsonProperty member, JsonContainerContract collectionContract)
private void SerializePrimitive(JsonWriter writer, object value, JsonPrimitiveContract contract, JsonProperty member, JsonContainerContract containerContract, JsonProperty containerProperty)
{
if (contract.UnderlyingType == typeof (byte[]))
{
bool includeTypeDetails = ShouldWriteType(TypeNameHandling.Objects, contract, member, collectionContract);
bool includeTypeDetails = ShouldWriteType(TypeNameHandling.Objects, contract, member, containerContract, containerProperty);
if (includeTypeDetails)
{
writer.WriteStartObject();
@@ -96,7 +96,7 @@ namespace Newtonsoft.Json.Serialization
writer.WriteValue(value);
}
private void SerializeValue(JsonWriter writer, object value, JsonContract valueContract, JsonProperty member, JsonContainerContract collectionContract)
private void SerializeValue(JsonWriter writer, object value, JsonContract valueContract, JsonProperty member, JsonContainerContract containerContract, JsonProperty containerProperty)
{
if (value == null)
{
@@ -106,43 +106,44 @@ namespace Newtonsoft.Json.Serialization
JsonConverter converter;
if ((((converter = (member != null) ? member.Converter : null) != null)
|| ((converter = (collectionContract != null) ? collectionContract.ItemConverter : null) != null)
|| ((converter = (containerProperty != null) ? containerProperty.ItemConverter : null) != null)
|| ((converter = (containerContract != null) ? containerContract.ItemConverter : null) != null)
|| ((converter = valueContract.Converter) != null)
|| ((converter = Serializer.GetMatchingConverter(valueContract.UnderlyingType)) != null)
|| ((converter = valueContract.InternalConverter) != null))
&& converter.CanWrite)
{
SerializeConvertable(writer, converter, value, valueContract, collectionContract);
SerializeConvertable(writer, converter, value, valueContract, containerContract, containerProperty);
return;
}
switch (valueContract.ContractType)
{
case JsonContractType.Object:
SerializeObject(writer, value, (JsonObjectContract) valueContract, member, collectionContract);
SerializeObject(writer, value, (JsonObjectContract)valueContract, member, containerContract, containerProperty);
break;
case JsonContractType.Array:
JsonArrayContract arrayContract = (JsonArrayContract) valueContract;
SerializeList(writer, arrayContract.CreateWrapper(value), arrayContract, member, collectionContract);
SerializeList(writer, arrayContract.CreateWrapper(value), arrayContract, member, containerContract, containerProperty);
break;
case JsonContractType.Primitive:
SerializePrimitive(writer, value, (JsonPrimitiveContract)valueContract, member, collectionContract);
SerializePrimitive(writer, value, (JsonPrimitiveContract)valueContract, member, containerContract, containerProperty);
break;
case JsonContractType.String:
SerializeString(writer, value, (JsonStringContract) valueContract);
SerializeString(writer, value, (JsonStringContract)valueContract);
break;
case JsonContractType.Dictionary:
JsonDictionaryContract dictionaryContract = (JsonDictionaryContract) valueContract;
SerializeDictionary(writer, dictionaryContract.CreateWrapper(value), dictionaryContract, member, collectionContract);
SerializeDictionary(writer, dictionaryContract.CreateWrapper(value), dictionaryContract, member, containerContract, containerProperty);
break;
#if !(NET35 || NET20 || WINDOWS_PHONE || PORTABLE)
case JsonContractType.Dynamic:
SerializeDynamic(writer, (IDynamicMetaObjectProvider)value, (JsonDynamicContract)valueContract, member, collectionContract);
SerializeDynamic(writer, (IDynamicMetaObjectProvider)value, (JsonDynamicContract)valueContract, member, containerContract, containerProperty);
break;
#endif
#if !(SILVERLIGHT || NETFX_CORE || PORTABLE)
case JsonContractType.Serializable:
SerializeISerializable(writer, (ISerializable)value, (JsonISerializableContract)valueContract, member, collectionContract);
SerializeISerializable(writer, (ISerializable)value, (JsonISerializableContract)valueContract, member, containerContract, containerProperty);
break;
#endif
case JsonContractType.Linq:
@@ -151,7 +152,7 @@ namespace Newtonsoft.Json.Serialization
}
}
private bool? ResolveIsReference(JsonContract contract, JsonProperty property, JsonContainerContract collectionContract)
private bool? ResolveIsReference(JsonContract contract, JsonProperty property, JsonContainerContract collectionContract, JsonProperty containerProperty)
{
bool? isReference = null;
@@ -159,6 +160,9 @@ namespace Newtonsoft.Json.Serialization
if (property != null)
isReference = property.IsReference;
if (isReference == null && containerProperty != null)
isReference = containerProperty.ItemIsReference;
if (isReference == null && collectionContract != null)
isReference = collectionContract.ItemIsReference;
@@ -168,14 +172,14 @@ namespace Newtonsoft.Json.Serialization
return isReference;
}
private bool ShouldWriteReference(object value, JsonProperty property, JsonContract valueContract, JsonContainerContract collectionContract)
private bool ShouldWriteReference(object value, JsonProperty property, JsonContract valueContract, JsonContainerContract collectionContract, JsonProperty containerProperty)
{
if (value == null)
return false;
if (valueContract.ContractType == JsonContractType.Primitive || valueContract.ContractType == JsonContractType.String)
return false;
bool? isReference = ResolveIsReference(valueContract, property, collectionContract);
bool? isReference = ResolveIsReference(valueContract, property, collectionContract, containerProperty);
if (isReference == null)
{
@@ -191,31 +195,6 @@ namespace Newtonsoft.Json.Serialization
return Serializer.ReferenceResolver.IsReferenced(this, value);
}
private void WriteMemberInfoProperty(JsonWriter writer, object memberValue, JsonProperty property, JsonContract contract, JsonObjectContract collectionContract)
{
string propertyName = property.PropertyName;
if (ShouldWriteReference(memberValue, property, contract, collectionContract))
{
writer.WritePropertyName(propertyName);
WriteReference(writer, memberValue);
return;
}
if (!CheckForCircularReference(memberValue, property, contract, collectionContract))
return;
if (memberValue == null)
{
Required resolvedRequired = property._required ?? collectionContract.ItemRequired ?? Required.Default;
if (resolvedRequired == Required.Always)
throw new JsonSerializationException("Cannot write a null value for property '{0}'. Property requires a value.".FormatWith(CultureInfo.InvariantCulture, property.PropertyName));
}
writer.WritePropertyName(propertyName);
SerializeValue(writer, memberValue, contract, property, collectionContract);
}
private bool ShouldWriteProperty(object memberValue, JsonProperty property)
{
if (property.NullValueHandling.GetValueOrDefault(Serializer.NullValueHandling) == NullValueHandling.Ignore &&
@@ -229,7 +208,7 @@ namespace Newtonsoft.Json.Serialization
return true;
}
private bool CheckForCircularReference(object value, JsonProperty property, JsonContract contract, JsonContainerContract collectionContract)
private bool CheckForCircularReference(object value, JsonProperty property, JsonContract contract, JsonContainerContract containerContract, JsonProperty containerProperty)
{
if (value == null || contract.ContractType == JsonContractType.Primitive || contract.ContractType == JsonContractType.String)
return true;
@@ -239,8 +218,11 @@ namespace Newtonsoft.Json.Serialization
if (property != null)
referenceLoopHandling = property.ReferenceLoopHandling;
if (referenceLoopHandling == null && collectionContract != null)
referenceLoopHandling = collectionContract.ItemReferenceLoopHandling;
if (referenceLoopHandling == null && containerProperty != null)
referenceLoopHandling = containerProperty.ItemReferenceLoopHandling;
if (referenceLoopHandling == null && containerContract != null)
referenceLoopHandling = containerContract.ItemReferenceLoopHandling;
if (_serializeStack.IndexOf(value) != -1)
{
@@ -321,13 +303,13 @@ namespace Newtonsoft.Json.Serialization
contract.InvokeOnSerialized(value, Serializer.Context);
}
private void SerializeObject(JsonWriter writer, object value, JsonObjectContract contract, JsonProperty member, JsonContainerContract collectionContract)
private void SerializeObject(JsonWriter writer, object value, JsonObjectContract contract, JsonProperty member, JsonContainerContract collectionContract, JsonProperty containerProperty)
{
contract.InvokeOnSerializing(value, Serializer.Context);
_serializeStack.Add(value);
WriteObjectStart(writer, value, contract, member, collectionContract);
WriteObjectStart(writer, value, contract, member, collectionContract, containerProperty);
int initialDepth = writer.Top;
@@ -345,7 +327,27 @@ namespace Newtonsoft.Json.Serialization
if (ShouldWriteProperty(memberValue, property))
{
WriteMemberInfoProperty(writer, memberValue, property, memberContract, contract);
string propertyName = property.PropertyName;
if (ShouldWriteReference(memberValue, property, memberContract, contract, member))
{
writer.WritePropertyName(propertyName);
WriteReference(writer, memberValue);
continue;
}
if (!CheckForCircularReference(memberValue, property, memberContract, contract, member))
continue;
if (memberValue == null)
{
Required resolvedRequired = property._required ?? contract.ItemRequired ?? Required.Default;
if (resolvedRequired == Required.Always)
throw new JsonSerializationException("Cannot write a null value for property '{0}'. Property requires a value.".FormatWith(CultureInfo.InvariantCulture, property.PropertyName));
}
writer.WritePropertyName(propertyName);
SerializeValue(writer, memberValue, memberContract, property, contract, member);
}
}
}
@@ -365,17 +367,17 @@ namespace Newtonsoft.Json.Serialization
contract.InvokeOnSerialized(value, Serializer.Context);
}
private void WriteObjectStart(JsonWriter writer, object value, JsonContract contract, JsonProperty member, JsonContainerContract collectionContract)
private void WriteObjectStart(JsonWriter writer, object value, JsonContract contract, JsonProperty member, JsonContainerContract collectionContract, JsonProperty containerProperty)
{
writer.WriteStartObject();
bool isReference = ResolveIsReference(contract, member, collectionContract) ?? HasFlag(Serializer.PreserveReferencesHandling, PreserveReferencesHandling.Objects);
bool isReference = ResolveIsReference(contract, member, collectionContract, containerProperty) ?? HasFlag(Serializer.PreserveReferencesHandling, PreserveReferencesHandling.Objects);
if (isReference)
{
writer.WritePropertyName(JsonTypeReflector.IdPropertyName);
writer.WriteValue(Serializer.ReferenceResolver.GetReference(this, value));
}
if (ShouldWriteType(TypeNameHandling.Objects, contract, member, collectionContract))
if (ShouldWriteType(TypeNameHandling.Objects, contract, member, collectionContract, containerProperty))
{
WriteTypeProperty(writer, contract.UnderlyingType);
}
@@ -402,15 +404,15 @@ namespace Newtonsoft.Json.Serialization
return ((value & flag) == flag);
}
private void SerializeConvertable(JsonWriter writer, JsonConverter converter, object value, JsonContract contract, JsonContainerContract collectionContract)
private void SerializeConvertable(JsonWriter writer, JsonConverter converter, object value, JsonContract contract, JsonContainerContract collectionContract, JsonProperty containerProperty)
{
if (ShouldWriteReference(value, null, contract, collectionContract))
if (ShouldWriteReference(value, null, contract, collectionContract, containerProperty))
{
WriteReference(writer, value);
}
else
{
if (!CheckForCircularReference(value, null, contract, collectionContract))
if (!CheckForCircularReference(value, null, contract, collectionContract, containerProperty))
return;
_serializeStack.Add(value);
@@ -421,13 +423,13 @@ namespace Newtonsoft.Json.Serialization
}
}
private void SerializeList(JsonWriter writer, IWrappedCollection values, JsonArrayContract contract, JsonProperty member, JsonContainerContract collectionContract)
private void SerializeList(JsonWriter writer, IWrappedCollection values, JsonArrayContract contract, JsonProperty member, JsonContainerContract collectionContract, JsonProperty containerProperty)
{
contract.InvokeOnSerializing(values.UnderlyingCollection, Serializer.Context);
_serializeStack.Add(values.UnderlyingCollection);
bool hasWrittenMetadataObject = WriteStartArray(writer, values, contract, member, collectionContract);
bool hasWrittenMetadataObject = WriteStartArray(writer, values, contract, member, collectionContract, containerProperty);
writer.WriteStartArray();
@@ -441,15 +443,15 @@ namespace Newtonsoft.Json.Serialization
{
JsonContract valueContract = contract.FinalItemContract ?? GetContractSafe(value);
if (ShouldWriteReference(value, null, valueContract, contract))
if (ShouldWriteReference(value, null, valueContract, contract, member))
{
WriteReference(writer, value);
}
else
{
if (CheckForCircularReference(value, null, valueContract, contract))
if (CheckForCircularReference(value, null, valueContract, contract, member))
{
SerializeValue(writer, value, valueContract, null, contract);
SerializeValue(writer, value, valueContract, null, contract, member);
}
}
}
@@ -476,10 +478,10 @@ namespace Newtonsoft.Json.Serialization
contract.InvokeOnSerialized(values.UnderlyingCollection, Serializer.Context);
}
private bool WriteStartArray(JsonWriter writer, IWrappedCollection values, JsonArrayContract contract, JsonProperty member, JsonContainerContract collectionContract)
private bool WriteStartArray(JsonWriter writer, IWrappedCollection values, JsonArrayContract contract, JsonProperty member, JsonContainerContract containerContract, JsonProperty containerProperty)
{
bool isReference = ResolveIsReference(contract, member, collectionContract) ?? HasFlag(Serializer.PreserveReferencesHandling, PreserveReferencesHandling.Arrays);
bool includeTypeDetails = ShouldWriteType(TypeNameHandling.Arrays, contract, member, collectionContract);
bool isReference = ResolveIsReference(contract, member, containerContract, containerProperty) ?? HasFlag(Serializer.PreserveReferencesHandling, PreserveReferencesHandling.Arrays);
bool includeTypeDetails = ShouldWriteType(TypeNameHandling.Arrays, contract, member, containerContract, containerProperty);
bool writeMetadataObject = isReference || includeTypeDetails;
if (writeMetadataObject)
@@ -509,7 +511,7 @@ namespace Newtonsoft.Json.Serialization
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Portability", "CA1903:UseOnlyApiFromTargetedFramework", MessageId = "System.Security.SecuritySafeCriticalAttribute")]
[SecuritySafeCritical]
#endif
private void SerializeISerializable(JsonWriter writer, ISerializable value, JsonISerializableContract contract, JsonProperty member, JsonContainerContract collectionContract)
private void SerializeISerializable(JsonWriter writer, ISerializable value, JsonISerializableContract contract, JsonProperty member, JsonContainerContract collectionContract, JsonProperty containerProperty)
{
if (!JsonTypeReflector.FullyTrusted)
{
@@ -520,7 +522,7 @@ To fix this error either change the environment to be fully trusted, change the
contract.InvokeOnSerializing(value, Serializer.Context);
_serializeStack.Add(value);
WriteObjectStart(writer, value, contract, member, collectionContract);
WriteObjectStart(writer, value, contract, member, collectionContract, containerProperty);
SerializationInfo serializationInfo = new SerializationInfo(contract.UnderlyingType, new FormatterConverter());
value.GetObjectData(serializationInfo, Serializer.Context);
@@ -528,7 +530,7 @@ To fix this error either change the environment to be fully trusted, change the
foreach (SerializationEntry serializationEntry in serializationInfo)
{
writer.WritePropertyName(serializationEntry.Name);
SerializeValue(writer, serializationEntry.Value, GetContractSafe(serializationEntry.Value), null, null);
SerializeValue(writer, serializationEntry.Value, GetContractSafe(serializationEntry.Value), null, null, member);
}
writer.WriteEndObject();
@@ -539,12 +541,12 @@ To fix this error either change the environment to be fully trusted, change the
#endif
#if !(NET35 || NET20 || WINDOWS_PHONE || PORTABLE)
private void SerializeDynamic(JsonWriter writer, IDynamicMetaObjectProvider value, JsonDynamicContract contract, JsonProperty member, JsonContainerContract collectionContract)
private void SerializeDynamic(JsonWriter writer, IDynamicMetaObjectProvider value, JsonDynamicContract contract, JsonProperty member, JsonContainerContract collectionContract, JsonProperty containerProperty)
{
contract.InvokeOnSerializing(value, Serializer.Context);
_serializeStack.Add(value);
WriteObjectStart(writer, value, contract, member, collectionContract);
WriteObjectStart(writer, value, contract, member, collectionContract, containerProperty);
foreach (string memberName in value.GetDynamicMemberNames())
{
@@ -556,7 +558,7 @@ To fix this error either change the environment to be fully trusted, change the
: memberName;
writer.WritePropertyName(resolvedPropertyName);
SerializeValue(writer, memberValue, GetContractSafe(memberValue), null, null);
SerializeValue(writer, memberValue, GetContractSafe(memberValue), null, null, member);
}
}
@@ -567,43 +569,42 @@ To fix this error either change the environment to be fully trusted, change the
}
#endif
private bool ShouldWriteType(TypeNameHandling typeNameHandlingFlag, JsonContract contract, JsonProperty member, JsonContainerContract collectionContract)
private bool ShouldWriteType(TypeNameHandling typeNameHandlingFlag, JsonContract contract, JsonProperty member, JsonContainerContract containerContract, JsonProperty containerProperty)
{
TypeNameHandling resolvedTypeNameHandling = ((member != null) ? member.TypeNameHandling : null)
?? ((collectionContract != null) ? collectionContract.ItemTypeNameHandling : null)
TypeNameHandling resolvedTypeNameHandling =
((member != null) ? member.TypeNameHandling : null)
?? ((containerProperty != null) ? containerProperty.ItemTypeNameHandling : null)
?? ((containerContract != null) ? containerContract.ItemTypeNameHandling : null)
?? Serializer.TypeNameHandling;
if (HasFlag(resolvedTypeNameHandling, typeNameHandlingFlag))
return true;
if (member != null)
// instance type and the property's type's contract default type are different (no need to put the type in JSON because the type will be created by default)
if (HasFlag(resolvedTypeNameHandling, TypeNameHandling.Auto))
{
if ((member.TypeNameHandling ?? Serializer.TypeNameHandling) == TypeNameHandling.Auto
// instance and property type are different
&& contract.UnderlyingType != member.PropertyType)
if (member != null)
{
JsonContract memberTypeContract = Serializer.ContractResolver.ResolveContract(member.PropertyType);
// instance type and the property's type's contract default type are different (no need to put the type in JSON because the type will be created by default)
if (contract.UnderlyingType != memberTypeContract.CreatedType)
if (contract.UnderlyingType != member.PropertyContract.CreatedType)
return true;
}
else if (containerContract != null && containerContract.ItemContract != null)
{
if (contract.UnderlyingType != containerContract.ItemContract.CreatedType)
return true;
}
}
else if (collectionContract != null && collectionContract.ItemContract != null)
{
if (Serializer.TypeNameHandling == TypeNameHandling.Auto && contract.UnderlyingType != collectionContract.ItemContract.CreatedType)
return true;
}
return false;
}
private void SerializeDictionary(JsonWriter writer, IWrappedDictionary values, JsonDictionaryContract contract, JsonProperty member, JsonContainerContract collectionContract)
private void SerializeDictionary(JsonWriter writer, IWrappedDictionary values, JsonDictionaryContract contract, JsonProperty member, JsonContainerContract collectionContract, JsonProperty containerProperty)
{
contract.InvokeOnSerializing(values.UnderlyingDictionary, Serializer.Context);
_serializeStack.Add(values.UnderlyingDictionary);
WriteObjectStart(writer, values.UnderlyingDictionary, contract, member, collectionContract);
WriteObjectStart(writer, values.UnderlyingDictionary, contract, member, collectionContract, containerProperty);
if (contract.ItemContract == null)
contract.ItemContract = Serializer.ContractResolver.ResolveContract(contract.DictionaryValueType ?? typeof(object));
@@ -626,19 +627,19 @@ To fix this error either change the environment to be fully trusted, change the
object value = entry.Value;
JsonContract valueContract = contract.FinalItemContract ?? GetContractSafe(value);
if (ShouldWriteReference(value, null, valueContract, contract))
if (ShouldWriteReference(value, null, valueContract, contract, member))
{
writer.WritePropertyName(propertyName);
WriteReference(writer, value);
}
else
{
if (!CheckForCircularReference(value, null, valueContract, contract))
if (!CheckForCircularReference(value, null, valueContract, contract, member))
continue;
writer.WritePropertyName(propertyName);
SerializeValue(writer, value, valueContract, null, contract);
SerializeValue(writer, value, valueContract, null, contract, member);
}
}
catch (Exception ex)