-Added ItemIsReference, ItemReferenceLoopHandling, ItemTypeNameHandling, ItemConverterType to JsonPropertyAttribute
This commit is contained in:
@@ -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()
|
||||
{
|
||||
|
||||
@@ -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
@@ -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)
|
||||
|
||||
Reference in New Issue
Block a user