-Fixed various schema generation bugs

-Renamed MemberHandler delegate to ObjectConstructor
This commit is contained in:
JamesNK
2010-02-05 23:14:06 +00:00
parent 35cd765fd7
commit 42bf89940d
24 changed files with 326 additions and 48 deletions
@@ -30,6 +30,11 @@ using System.Text;
using NUnit.Framework;
using Newtonsoft.Json.Schema;
using Newtonsoft.Json.Linq;
using System.IO;
using Newtonsoft.Json.Tests.TestObjects;
#if !SILVERLIGHT
using System.Data;
#endif
namespace Newtonsoft.Json.Tests.Schema
{
@@ -144,5 +149,53 @@ namespace Newtonsoft.Json.Tests.Schema
// true
}
private void GenerateSchemaAndSerializeFromType<T>(T value)
{
JsonSchemaGenerator generator = new JsonSchemaGenerator();
generator.UndefinedSchemaIdHandling = UndefinedSchemaIdHandling.UseAssemblyQualifiedName;
JsonSchema typeSchema = generator.Generate(typeof (T));
string schema = typeSchema.ToString();
string json = JsonConvert.SerializeObject(value, Formatting.Indented);
JToken token = JToken.ReadFrom(new JsonTextReader(new StringReader(json)));
List<string> errors = new List<string>();
token.Validate(typeSchema, (sender, args) =>
{
errors.Add(args.Message);
});
if (errors.Count > 0)
Assert.Fail("Schema generated for type '{0}' is not valid." + Environment.NewLine + string.Join(Environment.NewLine, errors.ToArray()), typeof(T));
}
[Test]
public void GenerateSchemaAndSerializeFromTypeTests()
{
GenerateSchemaAndSerializeFromType(new List<string> { "1", "Two", "III" });
GenerateSchemaAndSerializeFromType(new List<int> { 1 });
GenerateSchemaAndSerializeFromType(new Version("1.2.3.4"));
GenerateSchemaAndSerializeFromType(new Store());
GenerateSchemaAndSerializeFromType(new Person());
GenerateSchemaAndSerializeFromType(new PersonRaw());
GenerateSchemaAndSerializeFromType(new CircularReferenceClass() { Name = "I'm required" });
GenerateSchemaAndSerializeFromType(new CircularReferenceWithIdClass());
GenerateSchemaAndSerializeFromType(new ClassWithArray());
GenerateSchemaAndSerializeFromType(new ClassWithGuid());
#if !NET20 && !PocketPC
GenerateSchemaAndSerializeFromType(new NullableDateTimeTestClass());
#endif
#if !SILVERLIGHT
GenerateSchemaAndSerializeFromType(new DataSet());
#endif
GenerateSchemaAndSerializeFromType(new object());
GenerateSchemaAndSerializeFromType(1);
GenerateSchemaAndSerializeFromType("Hi");
GenerateSchemaAndSerializeFromType(new DateTime(2000, 12, 29, 23, 59, 0, DateTimeKind.Utc));
GenerateSchemaAndSerializeFromType(TimeSpan.FromTicks(1000000));
GenerateSchemaAndSerializeFromType(DBNull.Value);
GenerateSchemaAndSerializeFromType(new JsonPropertyWithHandlingValues());
}
}
}
@@ -59,14 +59,17 @@ namespace Newtonsoft.Json.Tests.Schema
""null""
],
""items"": {
""type"": ""string""
""type"": [
""string"",
""null""
]
}
}
}", json);
Dictionary<string, List<string>> value = new Dictionary<string, List<string>>
{
{"HasValue", new List<string>() { "first", "second"}},
{"HasValue", new List<string>() { "first", "second", null }},
{"NoValue", null}
};
@@ -282,7 +285,7 @@ namespace Newtonsoft.Json.Tests.Schema
Assert.AreEqual(JsonSchemaType.String | JsonSchemaType.Null, schema.Properties["Name"].Type);
Assert.AreEqual("MyExplicitId", schema.Id);
Assert.AreEqual(JsonSchemaType.Object, schema.Properties["Child"].Type);
Assert.AreEqual(JsonSchemaType.Object | JsonSchemaType.Null, schema.Properties["Child"].Type);
Assert.AreEqual(schema, schema.Properties["Child"]);
}
@@ -532,6 +535,90 @@ namespace Newtonsoft.Json.Tests.Schema
// should succeed
Assert.IsNotNull(jsonSchema);
}
[Test]
public void CircularReferenceWithMixedRequires()
{
JsonSchemaGenerator jsonSchemaGenerator = new JsonSchemaGenerator();
jsonSchemaGenerator.UndefinedSchemaIdHandling = UndefinedSchemaIdHandling.UseTypeName;
JsonSchema jsonSchema = jsonSchemaGenerator.Generate(typeof(CircularReferenceClass));
string json = jsonSchema.ToString();
Assert.AreEqual(@"{
""id"": ""Newtonsoft.Json.Tests.TestObjects.CircularReferenceClass"",
""optional"": true,
""type"": [
""object"",
""null""
],
""properties"": {
""Name"": {
""type"": ""string""
},
""Child"": {
""$ref"": ""Newtonsoft.Json.Tests.TestObjects.CircularReferenceClass""
}
}
}", json);
}
[Test]
public void JsonPropertyWithHandlingValues()
{
JsonSchemaGenerator jsonSchemaGenerator = new JsonSchemaGenerator();
jsonSchemaGenerator.UndefinedSchemaIdHandling = UndefinedSchemaIdHandling.UseTypeName;
JsonSchema jsonSchema = jsonSchemaGenerator.Generate(typeof(JsonPropertyWithHandlingValues));
string json = jsonSchema.ToString();
Assert.AreEqual(@"{
""id"": ""Newtonsoft.Json.Tests.TestObjects.JsonPropertyWithHandlingValues"",
""type"": [
""object"",
""null""
],
""properties"": {
""DefaultValueHandlingIgnoreProperty"": {
""optional"": true,
""type"": [
""string"",
""null""
],
""default"": ""Default!""
},
""DefaultValueHandlingIncludeProperty"": {
""type"": [
""string"",
""null""
],
""default"": ""Default!""
},
""NullValueHandlingIgnoreProperty"": {
""optional"": true,
""type"": [
""string"",
""null""
]
},
""NullValueHandlingIncludeProperty"": {
""type"": [
""string"",
""null""
]
},
""ReferenceLoopHandlingErrorProperty"": {
""$ref"": ""Newtonsoft.Json.Tests.TestObjects.JsonPropertyWithHandlingValues""
},
""ReferenceLoopHandlingIgnoreProperty"": {
""$ref"": ""Newtonsoft.Json.Tests.TestObjects.JsonPropertyWithHandlingValues""
},
""ReferenceLoopHandlingSerializeProperty"": {
""$ref"": ""Newtonsoft.Json.Tests.TestObjects.JsonPropertyWithHandlingValues""
}
}
}", json);
}
}
public class DMDSLBase
@@ -2546,6 +2546,19 @@ keyword such as type of business.""
internal DateTimeOffset _dateTimeOffsetValue;
internal Person _personValue;
internal Person _nullPersonValue;
internal int? _nullableInt;
internal bool _booleanValue;
internal byte _byteValue;
internal char _charValue;
internal DateTime _dateTimeValue;
internal decimal _decimalValue;
internal short _shortValue;
internal long _longValue;
internal sbyte _sbyteValue;
internal float _floatValue;
internal ushort _ushortValue;
internal uint _uintValue;
internal ulong _ulongValue;
public ISerializableTestObject(string stringValue, int intValue, DateTimeOffset dateTimeOffset, Person personValue)
{
@@ -2553,6 +2566,7 @@ keyword such as type of business.""
_intValue = intValue;
_dateTimeOffsetValue = dateTimeOffset;
_personValue = personValue;
_dateTimeValue = new DateTime(0, DateTimeKind.Utc);
}
protected ISerializableTestObject(SerializationInfo info, StreamingContext context)
@@ -2562,6 +2576,20 @@ keyword such as type of business.""
_dateTimeOffsetValue = (DateTimeOffset)info.GetValue("dateTimeOffsetValue", typeof(DateTimeOffset));
_personValue = (Person)info.GetValue("personValue", typeof(Person));
_nullPersonValue = (Person)info.GetValue("nullPersonValue", typeof(Person));
_nullableInt = (int?)info.GetValue("nullableInt", typeof(int?));
_booleanValue = info.GetBoolean("booleanValue");
_byteValue = info.GetByte("byteValue");
_charValue = info.GetChar("charValue");
_dateTimeValue = info.GetDateTime("dateTimeValue");
_decimalValue = info.GetDecimal("decimalValue");
_shortValue = info.GetInt16("shortValue");
_longValue = info.GetInt64("longValue");
_sbyteValue = info.GetSByte("sbyteValue");
_floatValue = info.GetSingle("floatValue");
_ushortValue = info.GetUInt16("ushortValue");
_uintValue = info.GetUInt32("uintValue");
_ulongValue = info.GetUInt64("ulongValue");
}
public void GetObjectData(SerializationInfo info, StreamingContext context)
@@ -2571,6 +2599,20 @@ keyword such as type of business.""
info.AddValue("dateTimeOffsetValue", _dateTimeOffsetValue);
info.AddValue("personValue", _personValue);
info.AddValue("nullPersonValue", _nullPersonValue);
info.AddValue("nullableInt", null);
info.AddValue("booleanValue", _booleanValue);
info.AddValue("byteValue", _byteValue);
info.AddValue("charValue", _charValue);
info.AddValue("dateTimeValue", _dateTimeValue);
info.AddValue("decimalValue", _decimalValue);
info.AddValue("shortValue", _shortValue);
info.AddValue("longValue", _longValue);
info.AddValue("sbyteValue", _sbyteValue);
info.AddValue("floatValue", _floatValue);
info.AddValue("ushortValue", _ushortValue);
info.AddValue("uintValue", _uintValue);
info.AddValue("ulongValue", _ulongValue);
}
}
@@ -2603,7 +2645,20 @@ keyword such as type of business.""
""BirthDate"": ""\/Date(946688461000)\/"",
""LastModified"": ""\/Date(946688461000)\/""
},
""nullPersonValue"": null
""nullPersonValue"": null,
""nullableInt"": null,
""booleanValue"": false,
""byteValue"": 0,
""charValue"": ""\u0000"",
""dateTimeValue"": ""\/Date(-62135596800000)\/"",
""decimalValue"": 0.0,
""shortValue"": 0,
""longValue"": 0,
""sbyteValue"": 0,
""floatValue"": 0.0,
""ushortValue"": 0,
""uintValue"": 0,
""ulongValue"": 0
}", json);
ISerializableTestObject o2 = JsonConvert.DeserializeObject<ISerializableTestObject>(json);
@@ -2612,6 +2667,7 @@ keyword such as type of business.""
Assert.AreEqual(dateTimeOffset, o2._dateTimeOffsetValue);
Assert.AreEqual("Name!", o2._personValue.Name);
Assert.AreEqual(null, o2._nullPersonValue);
Assert.AreEqual(null, o2._nullableInt);
}
#endif
}
@@ -34,6 +34,7 @@ namespace Newtonsoft.Json.Tests.TestObjects
{
[JsonProperty(Required = Required.Always)]
public string Name { get; set; }
[JsonProperty(NullValueHandling = NullValueHandling.Ignore)]
public CircularReferenceClass Child { get; set; }
}
}
}
@@ -164,7 +164,7 @@
<Compile Include="Serialization\JsonSerializerProxy.cs" />
<Compile Include="Serialization\JsonStringContract.cs" />
<Compile Include="Serialization\JsonTypeReflector.cs" />
<Compile Include="Serialization\MemberHandler.cs" />
<Compile Include="Serialization\ObjectConstructor.cs" />
<Compile Include="Serialization\OnErrorAttribute.cs" />
<Compile Include="Serialization\ReflectionValueProvider.cs" />
<Compile Include="StreamingContext.cs" />
@@ -187,6 +187,7 @@
<Compile Include="Utilities\LateBoundDelegateFactory.cs" />
<Compile Include="Utilities\ListWrapper.cs" />
<Compile Include="Utilities\MathUtils.cs" />
<Compile Include="Utilities\MethodCaller.cs" />
<Compile Include="Utilities\MiscellaneousUtils.cs" />
<Compile Include="Utilities\ReflectionUtils.cs" />
<Compile Include="Utilities\StringBuffer.cs" />
@@ -183,12 +183,13 @@
<Compile Include="Serialization\JsonStringContract.cs" />
<Compile Include="Serialization\JsonTypeReflector.cs" />
<Compile Include="Serialization\CachedAttributeGetter.cs" />
<Compile Include="Serialization\MemberHandler.cs" />
<Compile Include="Serialization\ObjectConstructor.cs" />
<Compile Include="Serialization\OnErrorAttribute.cs" />
<Compile Include="Serialization\ReflectionValueProvider.cs" />
<Compile Include="Utilities\Base64Encoder.cs" />
<Compile Include="Utilities\DynamicWrapper.cs" />
<Compile Include="Utilities\LateBoundDelegateFactory.cs" />
<Compile Include="Utilities\MethodCaller.cs" />
<Compile Include="Utilities\ThreadSafeStore.cs" />
<Compile Include="TypeNameHandling.cs" />
<Compile Include="Utilities\BidirectionalDictionary.cs" />
@@ -147,7 +147,7 @@
<Compile Include="Serialization\JsonSerializerInternalReader.cs" />
<Compile Include="Serialization\JsonSerializerInternalWriter.cs" />
<Compile Include="Serialization\JsonStringContract.cs" />
<Compile Include="Serialization\MemberHandler.cs" />
<Compile Include="Serialization\ObjectConstructor.cs" />
<Compile Include="Serialization\OnErrorAttribute.cs" />
<Compile Include="Serialization\ReflectionValueProvider.cs" />
<Compile Include="StreamingContext.cs" />
@@ -167,6 +167,7 @@
<Compile Include="Utilities\LateBoundDelegateFactory.cs" />
<Compile Include="Utilities\ListWrapper.cs" />
<Compile Include="Utilities\MathUtils.cs" />
<Compile Include="Utilities\MethodCaller.cs" />
<Compile Include="Utilities\MiscellaneousUtils.cs" />
<Compile Include="Utilities\ReflectionUtils.cs" />
<Compile Include="Utilities\StringBuffer.cs" />
+2 -1
View File
@@ -188,7 +188,8 @@
<Compile Include="Utilities\Base64Encoder.cs" />
<Compile Include="Utilities\DynamicWrapper.cs" />
<Compile Include="Utilities\LateBoundDelegateFactory.cs" />
<Compile Include="Serialization\MemberHandler.cs" />
<Compile Include="Serialization\ObjectConstructor.cs" />
<Compile Include="Utilities\MethodCaller.cs" />
<Compile Include="Utilities\ThreadSafeStore.cs" />
<Compile Include="TypeNameHandling.cs" />
<Compile Include="Utilities\BidirectionalDictionary.cs" />
@@ -49,8 +49,21 @@ using System.Security;
[assembly: InternalsVisibleTo("Newtonsoft.Json.Tests")]
#endif
#else
#if SILVERLIGHT
[assembly: InternalsVisibleTo("Newtonsoft.Json.Tests.Silverlight, PublicKey=0024000004800000940000000602000000240000525341310004000001000100f561df277c6c0b497d629032b410cdcf286e537c054724f7ffa0164345f62b3e642029d7a80cc351918955328c4adc8a048823ef90b0cf38ea7db0d729caf2b633c3babe08b0310198c1081995c19029bc675193744eab9d7345b8a67258ec17d112cebdbbb2a281487dceeafb9d83aa930f32103fbe1d2911425bc5744002c7")]
#elif PocketPC
[assembly: InternalsVisibleTo("Newtonsoft.Json.Tests.Compact, PublicKey=0024000004800000940000000602000000240000525341310004000001000100f561df277c6c0b497d629032b410cdcf286e537c054724f7ffa0164345f62b3e642029d7a80cc351918955328c4adc8a048823ef90b0cf38ea7db0d729caf2b633c3babe08b0310198c1081995c19029bc675193744eab9d7345b8a67258ec17d112cebdbbb2a281487dceeafb9d83aa930f32103fbe1d2911425bc5744002c7")]
#elif NET20
[assembly: InternalsVisibleTo("Newtonsoft.Json.Tests.Net20, PublicKey=0024000004800000940000000602000000240000525341310004000001000100f561df277c6c0b497d629032b410cdcf286e537c054724f7ffa0164345f62b3e642029d7a80cc351918955328c4adc8a048823ef90b0cf38ea7db0d729caf2b633c3babe08b0310198c1081995c19029bc675193744eab9d7345b8a67258ec17d112cebdbbb2a281487dceeafb9d83aa930f32103fbe1d2911425bc5744002c7")]
#else
[assembly: InternalsVisibleTo("Newtonsoft.Json.Tests, PublicKey=0024000004800000940000000602000000240000525341310004000001000100f561df277c6c0b497d629032b410cdcf286e537c054724f7ffa0164345f62b3e642029d7a80cc351918955328c4adc8a048823ef90b0cf38ea7db0d729caf2b633c3babe08b0310198c1081995c19029bc675193744eab9d7345b8a67258ec17d112cebdbbb2a281487dceeafb9d83aa930f32103fbe1d2911425bc5744002c7")]
#endif
#endif
[assembly: InternalsVisibleTo("Newtonsoft.Json.Dynamic, PublicKey=0024000004800000940000000602000000240000525341310004000001000100cbd8d53b9d7de30f1f1278f636ec462cf9c254991291e66ebb157a885638a517887633b898ccbcf0d5c5ff7be85a6abe9e765d0ac7cd33c68dac67e7e64530e8222101109f154ab14a941c490ac155cd1d4fcba0fabb49016b4ef28593b015cab5937da31172f03f67d09edda404b88a60023f062ae71d0b2e4438b74cc11dc9")]
@@ -155,7 +155,7 @@ namespace Newtonsoft.Json.Schema
_resolver = resolver;
return GenerateInternal(type, (!rootSchemaNullable) ? Required.Always : Required.Default);
return GenerateInternal(type, (!rootSchemaNullable) ? Required.Always : Required.Default, false);
}
private string GetTitle(Type type)
@@ -205,7 +205,7 @@ namespace Newtonsoft.Json.Schema
}
}
private JsonSchema GenerateInternal(Type type, Required valueRequired)
private JsonSchema GenerateInternal(Type type, Required valueRequired, bool optional)
{
ValidationUtils.ArgumentNotNull(type, "type");
@@ -216,7 +216,16 @@ namespace Newtonsoft.Json.Schema
{
JsonSchema resolvedSchema = _resolver.GetSchema(resolvedId);
if (resolvedSchema != null)
{
// resolved schema is not null but referencing member allows nulls
// change resolved schema to allow nulls. hacky but what are ya gonna do?
if (valueRequired != Required.Always && !HasFlag(resolvedSchema.Type, JsonSchemaType.Null))
resolvedSchema.Type |= JsonSchemaType.Null;
if (optional && resolvedSchema.Optional != true)
resolvedSchema.Optional = true;
return resolvedSchema;
}
}
// test for unresolved circular reference
@@ -230,12 +239,18 @@ namespace Newtonsoft.Json.Schema
if (explicitId != null)
CurrentSchema.Id = explicitId;
if (optional)
CurrentSchema.Optional = true;
CurrentSchema.Title = GetTitle(type);
CurrentSchema.Description = GetDescription(type);
JsonContract contract = ContractResolver.ResolveContract(type);
if (contract is JsonDictionaryContract)
if (contract.Converter != null || contract.InternalConverter != null)
{
// todo: Add GetSchema to JsonConverter and use here?
CurrentSchema.Type = JsonSchemaType.Any;
}
else if (contract is JsonDictionaryContract)
{
CurrentSchema.Type = AddNullType(JsonSchemaType.Object, valueRequired);
@@ -248,7 +263,7 @@ namespace Newtonsoft.Json.Schema
// can be converted to a string
if (typeof (IConvertible).IsAssignableFrom(keyType))
{
CurrentSchema.AdditionalProperties = GenerateInternal(valueType, Required.Default);
CurrentSchema.AdditionalProperties = GenerateInternal(valueType, Required.Default, false);
}
}
}
@@ -259,13 +274,13 @@ namespace Newtonsoft.Json.Schema
CurrentSchema.Id = GetTypeId(type, false);
JsonArrayAttribute arrayAttribute = JsonTypeReflector.GetJsonContainerAttribute(type) as JsonArrayAttribute;
bool allowNullItem = (arrayAttribute != null) ? arrayAttribute.AllowNullItems : false;
bool allowNullItem = (arrayAttribute != null) ? arrayAttribute.AllowNullItems : true;
Type collectionItemType = ReflectionUtils.GetCollectionItemType(type);
if (collectionItemType != null)
{
CurrentSchema.Items = new List<JsonSchema>();
CurrentSchema.Items.Add(GenerateInternal(collectionItemType, (!allowNullItem) ? Required.Always : Required.Default));
CurrentSchema.Items.Add(GenerateInternal(collectionItemType, (!allowNullItem) ? Required.Always : Required.Default, false));
}
}
else if (contract is JsonPrimitiveContract)
@@ -309,6 +324,10 @@ namespace Newtonsoft.Json.Schema
CurrentSchema.Type = schemaType;
}
else if (contract is JsonLinqContract)
{
CurrentSchema.Type = JsonSchemaType.Any;
}
else
{
throw new Exception("Unexpected contract type: {0}".FormatWith(CultureInfo.InvariantCulture, contract));
@@ -332,7 +351,10 @@ namespace Newtonsoft.Json.Schema
{
if (!property.Ignored)
{
JsonSchema propertySchema = GenerateInternal(property.PropertyType, property.Required);
bool optional = property.NullValueHandling == NullValueHandling.Ignore ||
property.DefaultValueHandling == DefaultValueHandling.Ignore;
JsonSchema propertySchema = GenerateInternal(property.PropertyType, property.Required, optional);
if (property.DefaultValue != null)
propertySchema.Default = JToken.FromObject(property.DefaultValue);
@@ -377,10 +399,7 @@ namespace Newtonsoft.Json.Schema
{
case TypeCode.Empty:
case TypeCode.Object:
if (ConvertUtils.CanConvertType(type, typeof(string), false))
return schemaType | JsonSchemaType.String;
return schemaType | JsonSchemaType.Object;
return schemaType | JsonSchemaType.String;
case TypeCode.DBNull:
return schemaType | JsonSchemaType.Null;
case TypeCode.Boolean:
@@ -323,7 +323,11 @@ namespace Newtonsoft.Json.Serialization
ConstructorInfo constructorInfo = objectType.GetConstructor(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance, null, new [] {typeof (SerializationInfo), typeof (StreamingContext)}, null);
if (constructorInfo != null)
contract.ISerializableCreator = LateBoundDelegateFactory.CreateMethodHandler(constructorInfo);
{
MethodCaller<object> methodCaller = LateBoundDelegateFactory.CreateMethodCall(constructorInfo);
contract.ISerializableCreator = (args => methodCaller(null, args));
}
return contract;
}
@@ -41,7 +41,7 @@ namespace Newtonsoft.Json.Serialization
private bool _isCollectionItemTypeNullableType;
private Type _genericCollectionDefinitionType;
private Type _genericWrapperType;
private MemberHandler<object> _genericWrapperCreator;
private MethodCaller<object> _genericWrapperCreator;
/// <summary>
/// Initializes a new instance of the <see cref="JsonArrayContract"/> class.
@@ -66,10 +66,6 @@ namespace Newtonsoft.Json.Serialization
{
CreatedType = ReflectionUtils.MakeGenericType(typeof(List<>), CollectionItemType);
}
else
{
CreatedType = UnderlyingType;
}
}
internal IWrappedCollection CreateWrapper(object list)
@@ -83,7 +79,7 @@ namespace Newtonsoft.Json.Serialization
ConstructorInfo genericWrapperConstructor = _genericWrapperType.GetConstructor(new[] { _genericCollectionDefinitionType });
#if !PocketPC && !SILVERLIGHT
_genericWrapperCreator = LateBoundDelegateFactory.CreateMethodHandler(genericWrapperConstructor);
_genericWrapperCreator = LateBoundDelegateFactory.CreateMethodCall(genericWrapperConstructor);
#else
_genericWrapperCreator = (target, args) => genericWrapperConstructor.Invoke(new[] { args[0] });
#endif
@@ -147,6 +147,7 @@ namespace Newtonsoft.Json.Serialization
ValidationUtils.ArgumentNotNull(underlyingType, "underlyingType");
UnderlyingType = underlyingType;
CreatedType = underlyingType;
}
}
}
@@ -41,7 +41,7 @@ namespace Newtonsoft.Json.Serialization
private readonly Type _genericCollectionDefinitionType;
private Type _genericWrapperType;
private MemberHandler<object> _genericWrapperCreator;
private MethodCaller<object> _genericWrapperCreator;
/// <summary>
/// Initializes a new instance of the <see cref="JsonDictionaryContract"/> class.
@@ -69,10 +69,6 @@ namespace Newtonsoft.Json.Serialization
{
CreatedType = ReflectionUtils.MakeGenericType(typeof(Dictionary<,>), keyType, valueType);
}
else
{
CreatedType = underlyingType;
}
}
internal IWrappedDictionary CreateWrapper(object dictionary)
@@ -86,7 +82,7 @@ namespace Newtonsoft.Json.Serialization
ConstructorInfo genericWrapperConstructor = _genericWrapperType.GetConstructor(new[] { _genericCollectionDefinitionType });
#if !PocketPC && !SILVERLIGHT
_genericWrapperCreator = LateBoundDelegateFactory.CreateMethodHandler(genericWrapperConstructor);
_genericWrapperCreator = LateBoundDelegateFactory.CreateMethodCall(genericWrapperConstructor);
#else
_genericWrapperCreator = (target, args) => genericWrapperConstructor.Invoke(new[] { args[0] });
#endif
@@ -37,7 +37,7 @@ namespace Newtonsoft.Json.Serialization
/// </summary>
public class JsonISerializableContract : JsonContract
{
public MemberHandler<object> ISerializableCreator { get; set; }
public ObjectConstructor<object> ISerializableCreator { get; set; }
/// <summary>
/// Initializes a new instance of the <see cref="JsonISerializableContract"/> class.
@@ -46,7 +46,6 @@ namespace Newtonsoft.Json.Serialization
public JsonISerializableContract(Type underlyingType)
: base(underlyingType)
{
CreatedType = underlyingType;
}
}
}
@@ -17,7 +17,6 @@ namespace Newtonsoft.Json.Serialization
public JsonLinqContract(Type underlyingType)
: base(underlyingType)
{
CreatedType = underlyingType;
}
}
}
@@ -59,7 +59,6 @@ namespace Newtonsoft.Json.Serialization
: base(underlyingType)
{
Properties = new JsonPropertyCollection(this);
CreatedType = underlyingType;
}
}
}
@@ -39,7 +39,6 @@ namespace Newtonsoft.Json.Serialization
public JsonPrimitiveContract(Type underlyingType)
: base(underlyingType)
{
CreatedType = underlyingType;
}
}
}
@@ -650,7 +650,7 @@ namespace Newtonsoft.Json.Serialization
if (contract.ISerializableCreator == null)
throw new JsonSerializationException("ISerializable type '{0}' does not have a valid constructor.".FormatWith(CultureInfo.InvariantCulture, objectType));
object createdObject = contract.ISerializableCreator(null, new object[] { serializationInfo, Serializer.Context });
object createdObject = contract.ISerializableCreator(new object[] { serializationInfo, Serializer.Context });
if (id != null)
Serializer.ReferenceResolver.AddReference(id, createdObject);
@@ -42,7 +42,6 @@ namespace Newtonsoft.Json.Serialization
public JsonStringContract(Type underlyingType)
: base(underlyingType)
{
CreatedType = underlyingType;
}
}
}
@@ -1,4 +0,0 @@
namespace Newtonsoft.Json.Serialization
{
public delegate object MemberHandler<T>(T target, params object[] args);
}
@@ -0,0 +1,29 @@
#region License
// Copyright (c) 2007 James Newton-King
//
// Permission is hereby granted, free of charge, to any person
// obtaining a copy of this software and associated documentation
// files (the "Software"), to deal in the Software without
// restriction, including without limitation the rights to use,
// copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following
// conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
// OTHER DEALINGS IN THE SOFTWARE.
#endregion
namespace Newtonsoft.Json.Serialization
{
public delegate object ObjectConstructor<T>(params object[] args);
}
@@ -31,7 +31,6 @@ using System.Reflection;
using System.Reflection.Emit;
using System.Text;
using System.Globalization;
using Newtonsoft.Json.Serialization;
namespace Newtonsoft.Json.Utilities
{
@@ -72,7 +71,7 @@ namespace Newtonsoft.Json.Utilities
throw new Exception("Could not create setter for {0}.".FormatWith(CultureInfo.InvariantCulture, memberInfo));
}
public static MemberHandler<object> CreateMethodHandler(MethodBase method)
public static MethodCaller<object> CreateMethodCall(MethodBase method)
{
DynamicMethod dynamicMethod = CreateDynamicMethod(method.ToString(), typeof(object), new[] { typeof(object), typeof(object[]) }, method.DeclaringType);
ILGenerator generator = dynamicMethod.GetILGenerator();
@@ -121,7 +120,7 @@ namespace Newtonsoft.Json.Utilities
generator.Emit(OpCodes.Ret);
return (MemberHandler<object>)dynamicMethod.CreateDelegate(typeof(MemberHandler<object>));
return (MethodCaller<object>)dynamicMethod.CreateDelegate(typeof(MethodCaller<object>));
}
@@ -0,0 +1,29 @@
#region License
// Copyright (c) 2007 James Newton-King
//
// Permission is hereby granted, free of charge, to any person
// obtaining a copy of this software and associated documentation
// files (the "Software"), to deal in the Software without
// restriction, including without limitation the rights to use,
// copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following
// conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
// OTHER DEALINGS IN THE SOFTWARE.
#endregion
namespace Newtonsoft.Json.Utilities
{
internal delegate object MethodCaller<T>(T target, params object[] args);
}