Add MissingMemberHandling to JsonObjectAttribute (#2050)
This commit is contained in:
@@ -27,6 +27,7 @@ using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using Newtonsoft.Json.Converters;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using Newtonsoft.Json.Tests.TestObjects;
|
||||
#if DNXCORE50
|
||||
using Xunit;
|
||||
@@ -154,6 +155,20 @@ namespace Newtonsoft.Json.Tests.Serialization
|
||||
});
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void MissingErrorAttribute()
|
||||
{
|
||||
string json = @"{""Missing"":1}";
|
||||
|
||||
ExceptionAssert.Throws<JsonSerializationException>(() => { JsonConvert.DeserializeObject<NameWithMissingError>(json); }, "Could not find member 'Missing' on object of type 'NameWithMissingError'. Path 'Missing', line 1, position 11.");
|
||||
}
|
||||
|
||||
[JsonObject(MissingMemberHandling = MissingMemberHandling.Error)]
|
||||
public class NameWithMissingError
|
||||
{
|
||||
public string First { get; set; }
|
||||
}
|
||||
|
||||
public class Name
|
||||
{
|
||||
public string First { get; set; }
|
||||
@@ -215,5 +230,46 @@ namespace Newtonsoft.Json.Tests.Serialization
|
||||
Assert.AreEqual(1, errors.Count);
|
||||
Assert.AreEqual("Could not find member 'firstERROR' on object of type 'Name'. Path 'name.firstERROR', line 1, position 20.", errors[0]);
|
||||
}
|
||||
|
||||
[JsonObject(MissingMemberHandling = MissingMemberHandling.Ignore)]
|
||||
public class SimpleExtendableObject
|
||||
{
|
||||
[JsonExtensionData]
|
||||
public IDictionary<string, object> Data { get; } = new Dictionary<string, object>();
|
||||
}
|
||||
|
||||
public class ObjectWithExtendableChild
|
||||
{
|
||||
public SimpleExtendableObject Data;
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestMissingMemberHandlingForDirectObjects()
|
||||
{
|
||||
string json = @"{""extensionData1"": [1,2,3]}";
|
||||
SimpleExtendableObject e2 = JsonConvert.DeserializeObject<SimpleExtendableObject>(json, new JsonSerializerSettings { MissingMemberHandling = MissingMemberHandling.Error });
|
||||
JArray o1 = (JArray)e2.Data["extensionData1"];
|
||||
Assert.AreEqual(JTokenType.Array, o1.Type);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestMissingMemberHandlingForChildObjects()
|
||||
{
|
||||
string json = @"{""Data"":{""extensionData1"": [1,2,3]}}";
|
||||
ObjectWithExtendableChild e3 = JsonConvert.DeserializeObject<ObjectWithExtendableChild>(json, new JsonSerializerSettings { MissingMemberHandling = MissingMemberHandling.Error });
|
||||
JArray o1 = (JArray)e3.Data.Data["extensionData1"];
|
||||
Assert.AreEqual(JTokenType.Array, o1.Type);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestMissingMemberHandlingForChildObjectsWithInvalidData()
|
||||
{
|
||||
string json = @"{""InvalidData"":{""extensionData1"": [1,2,3]}}";
|
||||
|
||||
ExceptionAssert.Throws<JsonSerializationException>(() =>
|
||||
{
|
||||
JsonConvert.DeserializeObject<ObjectWithExtendableChild>(json, new JsonSerializerSettings { MissingMemberHandling = MissingMemberHandling.Error });
|
||||
}, "Could not find member 'InvalidData' on object of type 'ObjectWithExtendableChild'. Path 'InvalidData', line 1, position 15.");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -34,7 +34,8 @@ namespace Newtonsoft.Json
|
||||
public sealed class JsonObjectAttribute : JsonContainerAttribute
|
||||
{
|
||||
private MemberSerialization _memberSerialization = MemberSerialization.OptOut;
|
||||
|
||||
internal MissingMemberHandling? _missingMemberHandling;
|
||||
|
||||
// yuck. can't set nullable properties on an attribute in C#
|
||||
// have to use this approach to get an unset default state
|
||||
internal Required? _itemRequired;
|
||||
@@ -50,6 +51,16 @@ namespace Newtonsoft.Json
|
||||
set => _memberSerialization = value;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the missing member handling used when deserializing this object.
|
||||
/// </summary>
|
||||
/// <value>The missing member handling.</value>
|
||||
public MissingMemberHandling MissingMemberHandling
|
||||
{
|
||||
get => _missingMemberHandling ?? default;
|
||||
set => _missingMemberHandling = value;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets how the object's properties with null values are handled during serialization and deserialization.
|
||||
/// </summary>
|
||||
|
||||
@@ -356,6 +356,7 @@ namespace Newtonsoft.Json.Serialization
|
||||
{
|
||||
contract.ItemRequired = attribute._itemRequired;
|
||||
contract.ItemNullValueHandling = attribute._itemNullValueHandling;
|
||||
contract.MissingMemberHandling = attribute._missingMemberHandling;
|
||||
|
||||
if (attribute.NamingStrategyType != null)
|
||||
{
|
||||
|
||||
@@ -44,6 +44,12 @@ namespace Newtonsoft.Json.Serialization
|
||||
/// <value>The member object serialization.</value>
|
||||
public MemberSerialization MemberSerialization { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the missing member handling used when deserializing this object.
|
||||
/// </summary>
|
||||
/// <value>The missing member handling.</value>
|
||||
public MissingMemberHandling? MissingMemberHandling { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets a value that indicates whether the object's properties are required.
|
||||
/// </summary>
|
||||
|
||||
@@ -2223,7 +2223,7 @@ namespace Newtonsoft.Json.Serialization
|
||||
TraceWriter.Trace(TraceLevel.Verbose, JsonPosition.FormatMessage(reader as IJsonLineInfo, reader.Path, "Could not find member '{0}' on {1}.".FormatWith(CultureInfo.InvariantCulture, memberName, contract.UnderlyingType)), null);
|
||||
}
|
||||
|
||||
if (Serializer._missingMemberHandling == MissingMemberHandling.Error)
|
||||
if ((contract.MissingMemberHandling ?? Serializer._missingMemberHandling) == MissingMemberHandling.Error)
|
||||
{
|
||||
throw JsonSerializationException.Create(reader, "Could not find member '{0}' on object of type '{1}'".FormatWith(CultureInfo.InvariantCulture, memberName, objectType.Name));
|
||||
}
|
||||
@@ -2342,7 +2342,7 @@ namespace Newtonsoft.Json.Serialization
|
||||
TraceWriter.Trace(TraceLevel.Verbose, JsonPosition.FormatMessage(reader as IJsonLineInfo, reader.Path, "Could not find member '{0}' on {1}".FormatWith(CultureInfo.InvariantCulture, propertyName, contract.UnderlyingType)), null);
|
||||
}
|
||||
|
||||
if (Serializer._missingMemberHandling == MissingMemberHandling.Error)
|
||||
if ((contract.MissingMemberHandling ?? Serializer._missingMemberHandling) == MissingMemberHandling.Error)
|
||||
{
|
||||
throw JsonSerializationException.Create(reader, "Could not find member '{0}' on object of type '{1}'".FormatWith(CultureInfo.InvariantCulture, propertyName, contract.UnderlyingType.Name));
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user