-Fixed various schema generation bugs
-Renamed MemberHandler delegate to ObjectConstructor
This commit is contained in:
@@ -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" />
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
Reference in New Issue
Block a user