-Lots of XML code comments

-Added type name handling to serializer
-Fixed various compilation warnings
This commit is contained in:
JamesNK
2009-05-30 06:13:51 +00:00
parent f0c5be266b
commit fec0ec5a1d
56 changed files with 1367 additions and 205 deletions
+212 -14
View File
@@ -44,6 +44,7 @@ using System.Runtime.Serialization.Json;
#endif
using Newtonsoft.Json.Tests.TestObjects;
using System.Runtime.Serialization;
using System.Globalization;
namespace Newtonsoft.Json.Tests
{
@@ -2048,20 +2049,20 @@ keyword such as type of business.""
WriteEscapedJson(json);
Assert.AreEqual(@"{
""$id"": ""1"",
""value"": [
""$values"": [
null,
{
""$id"": ""2"",
""value"": [
""$values"": [
null
]
},
{
""$id"": ""3"",
""value"": [
""$values"": [
{
""$id"": ""4"",
""value"": [
""$values"": [
{
""$ref"": ""1""
}
@@ -2078,20 +2079,20 @@ keyword such as type of business.""
{
string json = @"{
""$id"": ""1"",
""value"": [
""$values"": [
null,
{
""$id"": ""2"",
""value"": [
""$values"": [
null
]
},
{
""$id"": ""3"",
""value"": [
""$values"": [
{
""$id"": ""4"",
""value"": [
""$values"": [
{
""$ref"": ""1""
}
@@ -2119,20 +2120,20 @@ keyword such as type of business.""
{
string json = @"{
""$id"": ""1"",
""value"": [
""$values"": [
null,
{
""$id"": ""2"",
""value"": [
""$values"": [
null
]
},
{
""$id"": ""3"",
""value"": [
""$values"": [
{
""$id"": ""4"",
""value"": [
""$values"": [
{
""$ref"": ""1""
}
@@ -2245,7 +2246,7 @@ keyword such as type of business.""
{
CircularReferenceClass circularReferenceClass = (CircularReferenceClass) value;
string reference = serializer.ReferenceResolver.ResolveReference(circularReferenceClass);
string reference = serializer.ReferenceResolver.GetReference(circularReferenceClass);
JObject me = new JObject();
me["$id"] = new JValue(reference);
@@ -2271,7 +2272,7 @@ keyword such as type of business.""
else
{
string reference = (string)o["$ref"];
return serializer.ReferenceResolver.ResolveObject(reference);
return serializer.ReferenceResolver.ResolveReference(reference);
}
}
@@ -2351,5 +2352,202 @@ keyword such as type of business.""
Assert.AreEqual("c3", c1.Child.Child.Name);
Assert.AreEqual("c1", c1.Child.Child.Child.Name);
}
[Test]
public void WriteTypeNameForObjects()
{
string employeeRef = typeof(Employee).AssemblyQualifiedName;
Employee employee = new Employee();
string json = JsonConvert.SerializeObject(employee, Formatting.Indented, new JsonSerializerSettings
{
TypeNameHandling = TypeNameHandling.Objects
});
Assert.AreEqual(@"{
""$id"": ""1"",
""$type"": """ + employeeRef + @""",
""Name"": null,
""Manager"": null
}", json);
}
[Test]
public void DeserializeTypeName()
{
string employeeRef = typeof(Employee).AssemblyQualifiedName;
string json = @"{
""$id"": ""1"",
""$type"": """ + employeeRef + @""",
""Name"": ""Name!"",
""Manager"": null
}";
object employee = JsonConvert.DeserializeObject(json, null, new JsonSerializerSettings
{
TypeNameHandling = TypeNameHandling.Objects
});
Assert.IsInstanceOfType(typeof(Employee), employee);
Assert.AreEqual("Name!", ((Employee)employee).Name);
}
[Test]
public void SerializeGenericObjectListWithTypeName()
{
string employeeRef = typeof(Employee).AssemblyQualifiedName;
string personRef = typeof(Person).AssemblyQualifiedName;
List<object> values = new List<object>
{
new Employee
{
Name = "Bob",
Manager = new Employee {Name = "Frank"}
},
new Person
{
Department = "Department",
BirthDate = new DateTime(2000, 12, 30, 0, 0, 0, DateTimeKind.Utc),
LastModified = new DateTime(2000, 12, 30, 0, 0, 0, DateTimeKind.Utc)
},
"String!",
int.MinValue
};
string json = JsonConvert.SerializeObject(values, Formatting.Indented, new JsonSerializerSettings
{
TypeNameHandling = TypeNameHandling.Objects
});
Assert.AreEqual(@"[
{
""$id"": ""1"",
""$type"": """ + employeeRef + @""",
""Name"": ""Bob"",
""Manager"": {
""$id"": ""2"",
""$type"": """ + employeeRef + @""",
""Name"": ""Frank"",
""Manager"": null
}
},
{
""$type"": """ + personRef + @""",
""Name"": null,
""BirthDate"": ""\/Date(978134400000)\/"",
""LastModified"": ""\/Date(978134400000)\/""
},
""String!"",
-2147483648
]", json);
}
[Test]
public void DeserializeGenericObjectListWithTypeName()
{
string employeeRef = typeof (Employee).AssemblyQualifiedName;
string personRef = typeof (Person).AssemblyQualifiedName;
string json = @"[
{
""$id"": ""1"",
""$type"": """ + employeeRef + @""",
""Name"": ""Bob"",
""Manager"": {
""$id"": ""2"",
""$type"": """ + employeeRef + @""",
""Name"": ""Frank"",
""Manager"": null
}
},
{
""$type"": """ + personRef + @""",
""Name"": null,
""BirthDate"": ""\/Date(978134400000)\/"",
""LastModified"": ""\/Date(978134400000)\/""
},
""String!"",
-2147483648
]";
List<object> values = (List<object>)JsonConvert.DeserializeObject(json, typeof(List<object>), new JsonSerializerSettings
{
TypeNameHandling = TypeNameHandling.Objects
});
Assert.AreEqual(4, values.Count);
Employee e = (Employee) values[0];
Person p = (Person) values[1];
Assert.AreEqual("Bob", e.Name);
Assert.AreEqual("Frank", e.Manager.Name);
Assert.AreEqual(null, p.Name);
Assert.AreEqual(new DateTime(2000, 12, 30, 0, 0, 0, DateTimeKind.Utc), p.BirthDate);
Assert.AreEqual(new DateTime(2000, 12, 30, 0, 0, 0, DateTimeKind.Utc), p.LastModified);
Assert.AreEqual("String!", values[2]);
Assert.AreEqual(int.MinValue, values[3]);
}
[Test]
[ExpectedException(typeof(JsonSerializationException))]
public void DeserializeWithBadTypeName()
{
string employeeRef = typeof(Employee).AssemblyQualifiedName;
string json = @"{
""$id"": ""1"",
""$type"": """ + employeeRef + @""",
""Name"": ""Name!"",
""Manager"": null
}";
JsonConvert.DeserializeObject(json, typeof(Person), new JsonSerializerSettings
{
TypeNameHandling = TypeNameHandling.Objects
});
}
[Test]
public void DeserializeTypeNameWithNoTypeNameHandling()
{
string employeeRef = typeof(Employee).AssemblyQualifiedName;
string json = @"{
""$id"": ""1"",
""$type"": """ + employeeRef + @""",
""Name"": ""Name!"",
""Manager"": null
}";
JObject o = (JObject)JsonConvert.DeserializeObject(json);
Assert.AreEqual(@"{
""Name"": ""Name!"",
""Manager"": null
}", o.ToString());
}
[Test]
[ExpectedException(typeof(JsonSerializationException), ExpectedMessage = "Type specified in JSON 'Newtonsoft.Json.Tests.TestObjects.Employee' was not resolved.")]
public void DeserializeTypeNameOnly()
{
string json = @"{
""$id"": ""1"",
""$type"": ""Newtonsoft.Json.Tests.TestObjects.Employee"",
""Name"": ""Name!"",
""Manager"": null
}";
JsonConvert.DeserializeObject(json, null, new JsonSerializerSettings
{
TypeNameHandling = TypeNameHandling.Objects
});
}
}
}
@@ -356,8 +356,6 @@ Parameter name: arrayIndex")]
}");
// Invalid property identifier character: ]. Line 3, position 9.
person = person;
}
[Test]
@@ -39,7 +39,7 @@ using System.Runtime.InteropServices;
//
// You can specify all the values or you can default the Revision and Build Numbers
// by using the '*' as shown below:
[assembly: AssemblyVersion("3.0.0.0")]
[assembly: AssemblyVersion("3.5.0.0")]
#if !PocketPC
[assembly: AssemblyFileVersion("3.0.0.0")]
[assembly: AssemblyFileVersion("3.5.0.0")]
#endif
@@ -142,8 +142,6 @@ namespace Newtonsoft.Json.Tests.Schema
bool valid = person.IsValid(schema);
// true
valid = valid;
}
}
@@ -1,4 +1,4 @@
#region License
#region License
// Copyright (c) 2007 James Newton-King
//
// Permission is hereby granted, free of charge, to any person
@@ -301,7 +301,7 @@ namespace Newtonsoft.Json.Tests.Schema
JsonMemberMappingCollection mappings = base.ResolveMappings(type);
JsonMemberMappingCollection c = new JsonMemberMappingCollection();
CollectionUtils.AddRange(c, (IEnumerable)mappings.Where(m => m.MappingName != "Root"));
CollectionUtils.AddRange(c, (IEnumerable)mappings.Where(m => m.PropertyName != "Root"));
return c;
}
@@ -15,6 +15,7 @@ namespace Newtonsoft.Json.Tests.TestObjects
public PrivateMembersClass()
{
i = default(int);
}
private string _privateString;
@@ -48,6 +48,7 @@ namespace Newtonsoft.Json.Converters
/// </summary>
/// <param name="writer">The <see cref="JsonWriter"/> to write to.</param>
/// <param name="value">The value.</param>
/// <param name="serializer">The calling serializer.</param>
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
if (value == null)
@@ -82,6 +83,7 @@ namespace Newtonsoft.Json.Converters
/// </summary>
/// <param name="reader">The <see cref="JsonReader"/> to read from.</param>
/// <param name="objectType">Type of the object.</param>
/// <param name="serializer">The calling serializer.</param>
/// <returns>The object value.</returns>
public override object ReadJson(JsonReader reader, Type objectType, JsonSerializer serializer)
{
@@ -30,16 +30,33 @@ using System.Text;
namespace Newtonsoft.Json.Converters
{
/// <summary>
/// Create a custom object
/// </summary>
/// <typeparam name="T"></typeparam>
public abstract class CustomCreationConverter<T> : JsonConverter
{
/// <summary>
/// Writes the JSON representation of the object.
/// </summary>
/// <param name="writer">The <see cref="JsonWriter"/> to write to.</param>
/// <param name="value">The value.</param>
/// <param name="serializer">The calling serializer.</param>
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
serializer.Serialize(writer, value);
}
/// <summary>
/// Reads the JSON representation of the object.
/// </summary>
/// <param name="reader">The <see cref="JsonReader"/> to read from.</param>
/// <param name="objectType">Type of the object.</param>
/// <param name="serializer">The calling serializer.</param>
/// <returns>The object value.</returns>
public override object ReadJson(JsonReader reader, Type objectType, JsonSerializer serializer)
{
T value = Create();
T value = Create(objectType);
if (value == null)
throw new JsonSerializationException("No object created.");
@@ -47,8 +64,20 @@ namespace Newtonsoft.Json.Converters
return value;
}
public abstract T Create();
/// <summary>
/// Creates an object which will then be populated by the serializer.
/// </summary>
/// <param name="objectType">Type of the object.</param>
/// <returns></returns>
public abstract T Create(Type objectType);
/// <summary>
/// Determines whether this instance can convert the specified object type.
/// </summary>
/// <param name="objectType">Type of the object.</param>
/// <returns>
/// <c>true</c> if this instance can convert the specified object type; otherwise, <c>false</c>.
/// </returns>
public override bool CanConvert(Type objectType)
{
return typeof (T).IsAssignableFrom(objectType);
@@ -40,6 +40,7 @@ namespace Newtonsoft.Json.Converters
/// Writes the JSON representation of the object.
/// </summary>
/// <param name="writer">The <see cref="JsonWriter"/> to write to.</param>
/// <param name="serializer">The calling serializer.</param>
/// <param name="value">The value.</param>
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
@@ -63,6 +64,7 @@ namespace Newtonsoft.Json.Converters
/// </summary>
/// <param name="reader">The <see cref="JsonReader"/> to read from.</param>
/// <param name="objectType">Type of the object.</param>
/// <param name="serializer">The calling serializer.</param>
/// <returns>The object value.</returns>
public override object ReadJson(JsonReader reader, Type objectType, JsonSerializer serializer)
{
@@ -1,7 +1,4 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Globalization;
using Newtonsoft.Json.Utilities;
@@ -17,6 +14,7 @@ namespace Newtonsoft.Json.Converters
/// </summary>
/// <param name="writer">The <see cref="JsonWriter"/> to write to.</param>
/// <param name="value">The value.</param>
/// <param name="serializer">The calling serializer.</param>
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
long ticks;
@@ -44,6 +42,7 @@ namespace Newtonsoft.Json.Converters
/// </summary>
/// <param name="reader">The <see cref="JsonReader"/> to read from.</param>
/// <param name="objectType">Type of the object.</param>
/// <param name="serializer">The calling serializer.</param>
/// <returns>The object value.</returns>
public override object ReadJson(JsonReader reader, Type objectType, JsonSerializer serializer)
{
@@ -24,9 +24,6 @@
#endregion
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Globalization;
using Newtonsoft.Json.Utilities;
@@ -43,6 +40,7 @@ namespace Newtonsoft.Json.Converters
/// </summary>
/// <param name="writer">The <see cref="JsonWriter"/> to write to.</param>
/// <param name="value">The value.</param>
/// <param name="serializer">The calling serializer.</param>
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
if (value == null)
@@ -65,6 +63,7 @@ namespace Newtonsoft.Json.Converters
/// </summary>
/// <param name="reader">The <see cref="JsonReader"/> to read from.</param>
/// <param name="objectType">Type of the object.</param>
/// <param name="serializer">The calling serializer.</param>
/// <returns>The object value.</returns>
public override object ReadJson(JsonReader reader, Type objectType, JsonSerializer serializer)
{
@@ -46,6 +46,10 @@ namespace Newtonsoft.Json.Converters
private const string DeclarationName = "?xml";
private const string JsonNamespaceUri = "http://james.newtonking.com/projects/json";
/// <summary>
/// Gets or sets the name of the root element to insert when deserializing to XML if the JSON structure has produces multiple root elements.
/// </summary>
/// <value>The name of the deserialize root element.</value>
public string DeserializeRootElementName { get; set; }
#region Writing
@@ -53,6 +57,7 @@ namespace Newtonsoft.Json.Converters
/// Writes the JSON representation of the object.
/// </summary>
/// <param name="writer">The <see cref="JsonWriter"/> to write to.</param>
/// <param name="serializer">The calling serializer.</param>
/// <param name="value">The value.</param>
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
@@ -260,6 +265,7 @@ namespace Newtonsoft.Json.Converters
/// </summary>
/// <param name="reader">The <see cref="JsonReader"/> to read from.</param>
/// <param name="objectType">Type of the object.</param>
/// <param name="serializer">The calling serializer.</param>
/// <returns>The object value.</returns>
public override object ReadJson(JsonReader reader, Type objectType, JsonSerializer serializer)
{
+17
View File
@@ -5,11 +5,28 @@ using System.Text;
namespace Newtonsoft.Json
{
/// <summary>
/// Provides an interface to enable a class to return line and position information.
/// </summary>
public interface IJsonLineInfo
{
/// <summary>
/// Gets a value indicating whether the class can return line information.
/// </summary>
/// <returns>
/// <c>true</c> if LineNumber and LinePosition can be provided; otherwise, <c>false</c>.
/// </returns>
bool HasLineInfo();
/// <summary>
/// Gets the current line number.
/// </summary>
/// <value>The current line number or 0 if no line information is available (for example, HasLineInfo returns false).</value>
int LineNumber { get; }
/// <summary>
/// Gets the current line position.
/// </summary>
/// <value>The current line position or 0 if no line information is available (for example, HasLineInfo returns false).</value>
int LinePosition { get; }
}
}
+5 -1
View File
@@ -31,13 +31,17 @@ using System.Text;
namespace Newtonsoft.Json
{
/// <summary>
/// Instructs the <see cref="JsonSerializer"/> how to serialize the object.
/// Instructs the <see cref="JsonSerializer"/> how to serialize the collection.
/// </summary>
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Interface, AllowMultiple = false)]
public sealed class JsonArrayAttribute : JsonContainerAttribute
{
private bool _allowNullItems;
/// <summary>
/// Gets or sets a value indicating whether null items are allowed in the collection.
/// </summary>
/// <value><c>true</c> if null items are allowed in the collection; otherwise, <c>false</c>.</value>
public bool AllowNullItems
{
get { return _allowNullItems; }
+20 -2
View File
@@ -36,14 +36,32 @@ namespace Newtonsoft.Json
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Interface, AllowMultiple = false)]
public abstract class JsonContainerAttribute : Attribute
{
/// <summary>
/// Gets or sets the id.
/// </summary>
/// <value>The id.</value>
public string Id { get; set; }
/// <summary>
/// Gets or sets the title.
/// </summary>
/// <value>The title.</value>
public string Title { get; set; }
/// <summary>
/// Gets or sets the description.
/// </summary>
/// <value>The description.</value>
public string Description { get; set; }
// yuck. can't set nullable properties on an attribute in C#
// have to use this approach to get an unset default state
internal bool? _isReference;
/// <summary>
/// Gets or sets a value that indicates whether to preserve object reference data.
/// </summary>
/// <value>
/// <c>true</c> to keep object reference; otherwise, <c>false</c>. The default is <c>false</c>.
/// </value>
public bool IsReference
{
get { return _isReference ?? default(bool); }
@@ -53,7 +71,7 @@ namespace Newtonsoft.Json
/// <summary>
/// Initializes a new instance of the <see cref="JsonContainerAttribute"/> class.
/// </summary>
public JsonContainerAttribute()
protected JsonContainerAttribute()
{
}
@@ -61,7 +79,7 @@ namespace Newtonsoft.Json
/// Initializes a new instance of the <see cref="JsonContainerAttribute"/> class with the specified container Id.
/// </summary>
/// <param name="id">The container Id.</param>
public JsonContainerAttribute(string id)
protected JsonContainerAttribute(string id)
{
Id = id;
}
@@ -14,18 +14,30 @@ namespace Newtonsoft.Json
internal DefaultValueHandling? _defaultValueHandling;
internal ReferenceLoopHandling? _referenceLoopHandling;
/// <summary>
/// Gets or sets the null value handling used when serializing this property.
/// </summary>
/// <value>The null value handling.</value>
public NullValueHandling NullValueHandling
{
get { return _nullValueHandling ?? default(NullValueHandling); }
set { _nullValueHandling = value; }
}
/// <summary>
/// Gets or sets the default value handling used when serializing this property.
/// </summary>
/// <value>The default value handling.</value>
public DefaultValueHandling DefaultValueHandling
{
get { return _defaultValueHandling ?? default(DefaultValueHandling); }
set { _defaultValueHandling = value; }
}
/// <summary>
/// Gets or sets the reference loop handling used when serializing this property.
/// </summary>
/// <value>The reference loop handling.</value>
public ReferenceLoopHandling ReferenceLoopHandling
{
get { return _referenceLoopHandling ?? default(ReferenceLoopHandling); }
@@ -38,6 +50,12 @@ namespace Newtonsoft.Json
/// <value>The name of the property.</value>
public string PropertyName { get; set; }
/// <summary>
/// Gets or sets a value indicating whether this property is required.
/// </summary>
/// <value>
/// <c>true</c> if this property is required; otherwise, <c>false</c>.
/// </value>
public bool IsRequired { get; set; }
/// <summary>
+1 -1
View File
@@ -199,7 +199,7 @@ namespace Newtonsoft.Json
}
/// <summary>
/// Reads the next Json token from the stream.
/// Reads the next JSON token from the stream.
/// </summary>
/// <returns>true if the next token was read successfully; false if there are no more tokens to read.</returns>
public abstract bool Read();
+10 -2
View File
@@ -24,8 +24,6 @@
#endregion
using System;
using System.Collections.Generic;
using System.Text;
namespace Newtonsoft.Json
{
@@ -34,7 +32,17 @@ namespace Newtonsoft.Json
/// </summary>
public class JsonReaderException : Exception
{
/// <summary>
/// Gets the line number indicating where the error occurred.
/// </summary>
/// <value>The line number indicating where the error occurred.</value>
public int LineNumber { get; private set; }
/// <summary>
/// Gets the line position indicating where the error occurred.
/// </summary>
/// <value>The line position indicating where the error occurred.</value>
public int LinePosition { get; private set; }
/// <summary>
+70 -4
View File
@@ -28,16 +28,18 @@ using System.Collections.Generic;
using System.IO;
using Newtonsoft.Json.Serialization;
using Newtonsoft.Json.Utilities;
using System.Runtime.Serialization;
namespace Newtonsoft.Json
{
/// <summary>
/// Serializes and deserializes objects into and from the Json format.
/// The <see cref="JsonSerializer"/> enables you to control how objects are encoded into Json.
/// Serializes and deserializes objects into and from the JSON format.
/// The <see cref="JsonSerializer"/> enables you to control how objects are encoded into JSON.
/// </summary>
public class JsonSerializer
{
#region Properties
private TypeNameHandling _typeNameHandling;
private PreserveReferencesHandling _preserveReferencesHandling;
private ReferenceLoopHandling _referenceLoopHandling;
private MissingMemberHandling _missingMemberHandling;
@@ -47,7 +49,11 @@ namespace Newtonsoft.Json
private JsonConverterCollection _converters;
private IMappingResolver _mappingResolver;
private IReferenceResolver _referenceResolver;
private SerializationBinder _binder;
/// <summary>
/// Gets or sets the <see cref="IReferenceResolver"/> used by the serializer when resolving references.
/// </summary>
public virtual IReferenceResolver ReferenceResolver
{
get
@@ -66,6 +72,42 @@ namespace Newtonsoft.Json
}
}
/// <summary>
/// Gets or sets the <see cref="SerializationBinder"/> used by the serializer when resolving type names.
/// </summary>
public virtual SerializationBinder Binder
{
get
{
return _binder;
}
set
{
if (value == null)
throw new ArgumentNullException("value", "Serialization binder cannot be null.");
_binder = value;
}
}
/// <summary>
/// Gets or sets how type name writing and reading is handled by the serializer.
/// </summary>
public virtual TypeNameHandling TypeNameHandling
{
get { return _typeNameHandling; }
set
{
if (value < TypeNameHandling.None || value > TypeNameHandling.All)
throw new ArgumentOutOfRangeException("value");
_typeNameHandling = value;
}
}
/// <summary>
/// Gets or sets how object references are preserved by the serializer.
/// </summary>
public virtual PreserveReferencesHandling PreserveReferencesHandling
{
get { return _preserveReferencesHandling; }
@@ -169,6 +211,10 @@ namespace Newtonsoft.Json
}
}
/// <summary>
/// Gets or sets the mapping resolver used by the serializer when
/// mapping JSON properties to .NET objet members.
/// </summary>
public virtual IMappingResolver MappingResolver
{
get { return _mappingResolver; }
@@ -186,6 +232,9 @@ namespace Newtonsoft.Json
_nullValueHandling = JsonSerializerSettings.DefaultNullValueHandling;
_defaultValueHandling = JsonSerializerSettings.DefaultDefaultValueHandling;
_objectCreationHandling = JsonSerializerSettings.DefaultObjectCreationHandling;
_preserveReferencesHandling = JsonSerializerSettings.DefaultPreserveReferencesHandling;
_typeNameHandling = JsonSerializerSettings.DefaultTypeNameHandling;
_binder = DefaultSerializationBinder.Instance;
}
/// <summary>
@@ -202,23 +251,40 @@ namespace Newtonsoft.Json
if (!CollectionUtils.IsNullOrEmpty(settings.Converters))
jsonSerializer.Converters.AddRange(settings.Converters);
jsonSerializer.TypeNameHandling = settings.TypeNameHandling;
jsonSerializer.PreserveReferencesHandling = settings.PreserveReferencesHandling;
jsonSerializer.ReferenceLoopHandling = settings.ReferenceLoopHandling;
jsonSerializer.MissingMemberHandling = settings.MissingMemberHandling;
jsonSerializer.ObjectCreationHandling = settings.ObjectCreationHandling;
jsonSerializer.NullValueHandling = settings.NullValueHandling;
jsonSerializer.DefaultValueHandling = settings.DefaultValueHandling;
jsonSerializer.MappingResolver = settings.MappingResolver;
if (settings.MappingResolver != null)
jsonSerializer.MappingResolver = settings.MappingResolver;
if (settings.ReferenceResolver != null)
jsonSerializer.ReferenceResolver = settings.ReferenceResolver;
if (settings.Binder != null)
jsonSerializer.Binder = settings.Binder;
}
return jsonSerializer;
}
/// <summary>
/// Populates the JSON values onto the target object.
/// </summary>
/// <param name="reader">The <see cref="TextReader"/> that contains the JSON structure to reader values from.</param>
/// <param name="target">The target object to populate values onto.</param>
public void Populate(TextReader reader, object target)
{
Populate(new JsonTextReader(reader), target);
}
/// <summary>
/// Populates the JSON values onto the target object.
/// </summary>
/// <param name="reader">The <see cref="JsonReader"/> that contains the JSON structure to reader values from.</param>
/// <param name="target">The target object to populate values onto.</param>
public void Populate(JsonReader reader, object target)
{
PopulateInternal(reader, target);
@@ -236,7 +302,7 @@ namespace Newtonsoft.Json
/// <summary>
/// Deserializes the Json structure contained by the specified <see cref="JsonReader"/>.
/// </summary>
/// <param name="reader">The <see cref="JsonReader"/> that contains the Json structure to deserialize.</param>
/// <param name="reader">The <see cref="JsonReader"/> that contains the JSON structure to deserialize.</param>
/// <returns>The <see cref="Object"/> being deserialized.</returns>
public object Deserialize(JsonReader reader)
{
+29 -1
View File
@@ -4,6 +4,7 @@ using System.Linq;
using System.Text;
using Newtonsoft.Json.Serialization;
using Newtonsoft.Json.Utilities;
using System.Runtime.Serialization;
namespace Newtonsoft.Json
{
@@ -18,6 +19,7 @@ namespace Newtonsoft.Json
internal const DefaultValueHandling DefaultDefaultValueHandling = DefaultValueHandling.Include;
internal const ObjectCreationHandling DefaultObjectCreationHandling = ObjectCreationHandling.Auto;
internal const PreserveReferencesHandling DefaultPreserveReferencesHandling = PreserveReferencesHandling.None;
internal const TypeNameHandling DefaultTypeNameHandling = TypeNameHandling.None;
/// <summary>
/// Gets or sets how reference loops (e.g. a class referencing itself) is handled.
@@ -49,8 +51,33 @@ namespace Newtonsoft.Json
/// </summary>
/// <value>The converters.</value>
public IList<JsonConverter> Converters { get; set; }
public IMappingResolver MappingResolver { get; set; }
/// <summary>
/// Gets or sets how object references are preserved by the serializer.
/// </summary>
/// <value>The preserve references handling.</value>
public PreserveReferencesHandling PreserveReferencesHandling { get; set; }
/// <summary>
/// Gets or sets how type name writing and reading is handled by the serializer.
/// </summary>
/// <value>The type name handling.</value>
public TypeNameHandling TypeNameHandling { get; set; }
/// <summary>
/// Gets or sets the mapping resolver used by the serializer when
/// mapping JSON properties to .NET objet members.
/// </summary>
/// <value>The mapping resolver.</value>
public IMappingResolver MappingResolver { get; set; }
/// <summary>
/// Gets or sets the <see cref="IReferenceResolver"/> used by the serializer when resolving references.
/// </summary>
/// <value>The reference resolver.</value>
public IReferenceResolver ReferenceResolver { get; set; }
/// <summary>
/// Gets or sets the <see cref="SerializationBinder"/> used by the serializer when resolving type names.
/// </summary>
/// <value>The binder.</value>
public SerializationBinder Binder { get; set; }
/// <summary>
/// Initializes a new instance of the <see cref="JsonSerializerSettings"/> class.
@@ -63,6 +90,7 @@ namespace Newtonsoft.Json
NullValueHandling = DefaultNullValueHandling;
DefaultValueHandling = DefaultDefaultValueHandling;
PreserveReferencesHandling = DefaultPreserveReferencesHandling;
TypeNameHandling = DefaultTypeNameHandling;
Converters = new List<JsonConverter>();
}
}
+19 -1
View File
@@ -276,7 +276,7 @@ namespace Newtonsoft.Json
}
/// <summary>
/// Reads the next Json token from the stream.
/// Reads the next JSON token from the stream.
/// </summary>
/// <returns>
/// true if the next token was read successfully; false if there are no more tokens to read.
@@ -846,11 +846,23 @@ namespace Newtonsoft.Json
_buffer.Clear();
}
/// <summary>
/// Gets a value indicating whether the class can return line information.
/// </summary>
/// <returns>
/// <c>true</c> if LineNumber and LinePosition can be provided; otherwise, <c>false</c>.
/// </returns>
public bool HasLineInfo()
{
return true;
}
/// <summary>
/// Gets the current line number.
/// </summary>
/// <value>
/// The current line number or 0 if no line information is available (for example, HasLineInfo returns false).
/// </value>
public int LineNumber
{
get
@@ -862,6 +874,12 @@ namespace Newtonsoft.Json
}
}
/// <summary>
/// Gets the current line position.
/// </summary>
/// <value>
/// The current line position or 0 if no line information is available (for example, HasLineInfo returns false).
/// </value>
public int LinePosition
{
get { return _currentLinePosition; }
+46 -10
View File
@@ -35,6 +35,9 @@ using System.Text.RegularExpressions;
namespace Newtonsoft.Json
{
/// <summary>
/// Represents a reader that provides <see cref="JsonSchema"/> validation.
/// </summary>
public class JsonValidatingReader : JsonReader, IJsonLineInfo
{
private class SchemaScope
@@ -75,15 +78,6 @@ namespace Newtonsoft.Json
private IEnumerable<string> GetRequiredProperties(JsonSchemaModel schema)
{
return schema.Properties.Where(p => !p.Value.Optional).Select(p => p.Key);
//if (schema == null)
// return Enumerable.Empty<string>();
//IEnumerable<string> extendedRequiredProperties = GetRequiredProperties(schema.Extends);
//if (_schema.Properties == null)
// return extendedRequiredProperties;
//return extendedRequiredProperties.Union(schema.Properties.Where(p => !(p.Value.Optional ?? false)).Select(p => p.Key));
}
}
@@ -93,29 +87,52 @@ namespace Newtonsoft.Json
private JsonSchemaModel _model;
private SchemaScope _currentScope;
/// <summary>
/// Sets an event handler for receiving schema validation errors.
/// </summary>
public event ValidationEventHandler ValidationEventHandler;
/// <summary>
/// Gets the text value of the current Json token.
/// </summary>
/// <value></value>
public override object Value
{
get { return _reader.Value; }
}
/// <summary>
/// Gets the depth of the current token in the JSON document.
/// </summary>
/// <value>The depth of the current token in the JSON document.</value>
public override int Depth
{
get { return _reader.Depth; }
}
/// <summary>
/// Gets the quotation mark character used to enclose the value of a string.
/// </summary>
/// <value></value>
public override char QuoteChar
{
get { return _reader.QuoteChar; }
protected internal set { }
}
/// <summary>
/// Gets the type of the current Json token.
/// </summary>
/// <value></value>
public override JsonToken TokenType
{
get { return _reader.TokenType; }
}
/// <summary>
/// Gets The Common Language Runtime (CLR) type for the current Json token.
/// </summary>
/// <value></value>
public override Type ValueType
{
get { return _reader.ValueType; }
@@ -204,6 +221,11 @@ namespace Newtonsoft.Json
throw exception;
}
/// <summary>
/// Initializes a new instance of the <see cref="JsonValidatingReader"/> class that
/// validates the content returned from the given <see cref="JsonReader"/>.
/// </summary>
/// <param name="reader">The <see cref="JsonReader"/> to read from while validating.</param>
public JsonValidatingReader(JsonReader reader)
{
ValidationUtils.ArgumentNotNull(reader, "reader");
@@ -211,6 +233,10 @@ namespace Newtonsoft.Json
_stack = new Stack<SchemaScope>();
}
/// <summary>
/// Gets or sets the schema.
/// </summary>
/// <value>The schema.</value>
public JsonSchema Schema
{
get { return _schema; }
@@ -224,6 +250,10 @@ namespace Newtonsoft.Json
}
}
/// <summary>
/// Gets the <see cref="JsonReader"/> used to construct this <see cref="JsonValidatingReader"/>.
/// </summary>
/// <value>The <see cref="JsonReader"/> specified in the constructor.</value>
public JsonReader Reader
{
get { return _reader; }
@@ -274,6 +304,12 @@ namespace Newtonsoft.Json
}
}
/// <summary>
/// Reads the next JSON token from the stream.
/// </summary>
/// <returns>
/// true if the next token was read successfully; false if there are no more tokens to read.
/// </returns>
public override bool Read()
{
if (!_reader.Read())
@@ -476,7 +512,7 @@ namespace Newtonsoft.Json
ValidateInEnumAndNotDisallowed(schema);
double value = Convert.ToDouble(_reader.Value);
double value = Convert.ToDouble(_reader.Value, CultureInfo.InvariantCulture);
if (schema.Maximum != null && value > schema.Maximum)
RaiseError("Float {0} exceeds maximum value of {1}.".FormatWith(CultureInfo.InvariantCulture, JsonConvert.ToString(value), schema.Maximum), schema);
+10 -5
View File
@@ -298,15 +298,20 @@ namespace Newtonsoft.Json
{
ValidationUtils.ArgumentNotNull(reader, "reader");
int currentDepth;
int initialDepth;
if (reader.TokenType == JsonToken.None)
currentDepth = -1;
initialDepth = -1;
else if (!IsStartToken(reader.TokenType))
currentDepth = reader.Depth + 1;
initialDepth = reader.Depth + 1;
else
currentDepth = reader.Depth;
initialDepth = reader.Depth;
WriteToken(reader, initialDepth);
}
internal void WriteToken(JsonReader reader, int initialDepth)
{
do
{
switch (reader.TokenType)
@@ -373,7 +378,7 @@ namespace Newtonsoft.Json
}
while (
// stop if we have reached the end of the token being read
currentDepth - 1 < reader.Depth - (IsEndToken(reader.TokenType) ? 1 : 0)
initialDepth - 1 < reader.Depth - (IsEndToken(reader.TokenType) ? 1 : 0)
&& reader.Read());
}
+6
View File
@@ -149,6 +149,12 @@ namespace Newtonsoft.Json.Linq
return FromObject(o, new JsonSerializer());
}
/// <summary>
/// Creates a <see cref="JArray"/> from an object.
/// </summary>
/// <param name="o">The object that will be used to create <see cref="JArray"/>.</param>
/// <param name="jsonSerializer">The <see cref="JsonSerializer"/> that will be used to read the object.</param>
/// <returns>A <see cref="JArray"/> with the values of the specified object</returns>
public static new JArray FromObject(object o, JsonSerializer jsonSerializer)
{
JToken token = FromObjectInternal(o, jsonSerializer);
+12
View File
@@ -230,6 +230,12 @@ namespace Newtonsoft.Json.Linq
return FromObject(o, new JsonSerializer());
}
/// <summary>
/// Creates a <see cref="JArray"/> from an object.
/// </summary>
/// <param name="o">The object that will be used to create <see cref="JArray"/>.</param>
/// <param name="jsonSerializer">The <see cref="JsonSerializer"/> that will be used to read the object.</param>
/// <returns>A <see cref="JArray"/> with the values of the specified object</returns>
public static new JObject FromObject(object o, JsonSerializer jsonSerializer)
{
JToken token = FromObjectInternal(o, jsonSerializer);
@@ -399,6 +405,12 @@ namespace Newtonsoft.Json.Linq
return ContentsHashCode();
}
/// <summary>
/// Returns an enumerator that iterates through the collection.
/// </summary>
/// <returns>
/// A <see cref="T:System.Collections.Generic.IEnumerator`1"/> that can be used to iterate through the collection.
/// </returns>
public IEnumerator<KeyValuePair<string, JToken>> GetEnumerator()
{
foreach (JProperty property in Properties())
+30 -4
View File
@@ -26,7 +26,6 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using Newtonsoft.Json.Utilities;
using System.Diagnostics;
@@ -164,6 +163,10 @@ namespace Newtonsoft.Json.Linq
{
}
/// <summary>
/// Adds the specified content immediately after this token.
/// </summary>
/// <param name="content">A content object that contains simple content or a collection of content objects to be added after this token.</param>
public void AddAfterSelf(object content)
{
if (_parent == null)
@@ -172,6 +175,10 @@ namespace Newtonsoft.Json.Linq
_parent.AddInternal((Next == null), this, content);
}
/// <summary>
/// Adds the specified content immediately before this token.
/// </summary>
/// <param name="content">A content object that contains simple content or a collection of content objects to be added before this token.</param>
public void AddBeforeSelf(object content)
{
if (_parent == null)
@@ -517,7 +524,7 @@ namespace Newtonsoft.Json.Linq
if (v == null || !ValidateFloat(v, true))
throw new ArgumentException("Can not convert {0} to Decimal.".FormatWith(CultureInfo.InvariantCulture, GetType(v)));
return (v.Value != null) ? (decimal?)Convert.ToDecimal(v.Value) : null;
return (v.Value != null) ? (decimal?)Convert.ToDecimal(v.Value, CultureInfo.InvariantCulture) : null;
}
/// <summary>
@@ -613,7 +620,7 @@ namespace Newtonsoft.Json.Linq
if (v == null || !ValidateFloat(v, true))
throw new ArgumentException("Can not convert {0} to Single.".FormatWith(CultureInfo.InvariantCulture, GetType(v)));
return (v.Value != null) ? (float?)Convert.ToSingle(v.Value) : null;
return (v.Value != null) ? (float?)Convert.ToSingle(v.Value, CultureInfo.InvariantCulture) : null;
}
/// <summary>
@@ -627,7 +634,7 @@ namespace Newtonsoft.Json.Linq
if (v == null || !ValidateFloat(v, false))
throw new ArgumentException("Can not convert {0} to Decimal.".FormatWith(CultureInfo.InvariantCulture, GetType(v)));
return Convert.ToDecimal(v.Value);
return Convert.ToDecimal(v.Value, CultureInfo.InvariantCulture);
}
/// <summary>
@@ -755,6 +762,10 @@ namespace Newtonsoft.Json.Linq
get { return this[key]; }
}
/// <summary>
/// Creates an <see cref="JsonReader"/> for this token.
/// </summary>
/// <returns>An <see cref="JsonReader"/> that can be used to read this token and its descendants.</returns>
public JsonReader CreateReader()
{
return new JTokenReader(this);
@@ -785,11 +796,26 @@ namespace Newtonsoft.Json.Linq
return FromObjectInternal(o, new JsonSerializer());
}
/// <summary>
/// Creates a <see cref="JToken"/> from an object using the specified <see cref="JsonSerializer"/>.
/// </summary>
/// <param name="o">The object that will be used to create <see cref="JToken"/>.</param>
/// <param name="jsonSerializer">The <see cref="JsonSerializer"/> that will be used when reading the object.</param>
/// <returns>A <see cref="JToken"/> with the value of the specified object</returns>
public static JToken FromObject(object o, JsonSerializer jsonSerializer)
{
return FromObjectInternal(o, jsonSerializer);
}
/// <summary>
/// Creates a <see cref="JToken"/> from a <see cref="JsonReader"/>.
/// </summary>
/// <param name="reader">An <see cref="JsonReader"/> positioned at the token to read into this <see cref="JToken"/>.</param>
/// <returns>
/// An <see cref="JToken"/> that contains the token and its descendant tokens
/// that were read from the reader. The runtime type of the token is determined
/// by the token type of the first token encountered in the reader.
/// </returns>
public static JToken ReadFrom(JsonReader reader)
{
ValidationUtils.ArgumentNotNull(reader, "reader");
+1 -1
View File
@@ -28,7 +28,7 @@ namespace Newtonsoft.Json.Linq
}
/// <summary>
/// Reads the next Json token from the stream.
/// Reads the next JSON token from the stream.
/// </summary>
/// <returns>
/// true if the next token was read successfully; false if there are no more tokens to read.
@@ -112,10 +112,12 @@
<Compile Include="Schema\UndefinedSchemaIdHandling.cs" />
<Compile Include="Schema\ValidationEventArgs.cs" />
<Compile Include="Schema\ValidationEventHandler.cs" />
<Compile Include="SerializationBinder.cs" />
<Compile Include="Serialization\CachedAttributeGetter.cs" />
<Compile Include="Serialization\CamelCaseMappingResolver.cs" />
<Compile Include="Serialization\DefaultMappingResolver.cs" />
<Compile Include="Serialization\DefaultReferenceResolver.cs" />
<Compile Include="Serialization\DefaultSerializationBinder.cs" />
<Compile Include="Serialization\IMappingResolver.cs" />
<Compile Include="Serialization\IReferenceResolver.cs" />
<Compile Include="Serialization\JsonMemberMapping.cs" />
@@ -133,6 +135,7 @@
<Compile Include="Serialization\JsonSerializerReader.cs" />
<Compile Include="Serialization\JsonSerializerWriter.cs" />
<Compile Include="Serialization\JsonTypeReflector.cs" />
<Compile Include="TypeNameHandling.cs" />
<Compile Include="Utilities\BidirectionalDictionary.cs" />
<Compile Include="Utilities\ConvertUtils.cs" />
<Compile Include="Utilities\CollectionWrapper.cs" />
@@ -102,15 +102,18 @@
<Compile Include="PreserveReferencesHandling.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="ReferenceLoopHandling.cs" />
<Compile Include="SerializationBinder.cs" />
<Compile Include="Serialization\CachedAttributeGetter.cs" />
<Compile Include="Serialization\CamelCaseMappingResolver.cs" />
<Compile Include="Serialization\DefaultMappingResolver.cs" />
<Compile Include="Serialization\DefaultReferenceResolver.cs" />
<Compile Include="Serialization\DefaultSerializationBinder.cs" />
<Compile Include="Serialization\IMappingResolver.cs" />
<Compile Include="Serialization\IReferenceResolver.cs" />
<Compile Include="Serialization\JsonSerializerProxy.cs" />
<Compile Include="Serialization\JsonSerializerReader.cs" />
<Compile Include="Serialization\JsonSerializerWriter.cs" />
<Compile Include="TypeNameHandling.cs" />
<Compile Include="Utilities\BidirectionalDictionary.cs" />
<Compile Include="Utilities\CollectionUtils.cs" />
<Compile Include="Utilities\CollectionWrapper.cs" />
@@ -143,6 +143,7 @@
<Compile Include="Schema\ValidationEventHandler.cs" />
<Compile Include="Serialization\CamelCaseMappingResolver.cs" />
<Compile Include="Serialization\DefaultMappingResolver.cs" />
<Compile Include="Serialization\DefaultSerializationBinder.cs" />
<Compile Include="Serialization\IMappingResolver.cs" />
<Compile Include="Serialization\JsonMemberMapping.cs" />
<Compile Include="Serialization\JsonMemberMappingCollection.cs" />
@@ -160,6 +161,7 @@
<Compile Include="Serialization\JsonSerializerWriter.cs" />
<Compile Include="Serialization\JsonTypeReflector.cs" />
<Compile Include="Serialization\CachedAttributeGetter.cs" />
<Compile Include="TypeNameHandling.cs" />
<Compile Include="Utilities\BidirectionalDictionary.cs" />
<Compile Include="Utilities\ConvertUtils.cs" />
<Compile Include="Utilities\CollectionWrapper.cs" />
@@ -29,12 +29,27 @@ using System.Text;
namespace Newtonsoft.Json
{
/// <summary>
/// Specifies reference handling options for the <see cref="JsonSerializer"/>.
/// </summary>
[Flags]
public enum PreserveReferencesHandling
{
/// <summary>
/// Do not preserve references when serializing types.
/// </summary>
None = 0,
/// <summary>
/// Preserve references when serializing into a JSON object structure.
/// </summary>
Objects = 1,
/// <summary>
/// Preserve references when serializing into a JSON array structure.
/// </summary>
Arrays = 2,
/// <summary>
/// Preserve references when serializing.
/// </summary>
All = Objects | Arrays
}
}
+1 -1
View File
@@ -30,7 +30,7 @@ using System.Text;
namespace Newtonsoft.Json
{
/// <summary>
/// Specifies reference loop handling options for the <see cref="JsonWriter"/>.
/// Specifies reference loop handling options for the <see cref="JsonSerializer"/>.
/// </summary>
public enum ReferenceLoopHandling
{
+22
View File
@@ -32,8 +32,19 @@ using Newtonsoft.Json.Utilities;
namespace Newtonsoft.Json.Schema
{
/// <summary>
/// Contains the JSON schema extension methods.
/// </summary>
public static class Extensions
{
/// <summary>
/// Determines whether the <see cref="JToken"/> is valid.
/// </summary>
/// <param name="source">The source <see cref="JToken"/> to test.</param>
/// <param name="schema">The schema to test with.</param>
/// <returns>
/// <c>true</c> if the specified <see cref="JToken"/> is valid; otherwise, <c>false</c>.
/// </returns>
public static bool IsValid(this JToken source, JsonSchema schema)
{
bool valid = true;
@@ -41,11 +52,22 @@ namespace Newtonsoft.Json.Schema
return valid;
}
/// <summary>
/// Validates the specified <see cref="JToken"/>.
/// </summary>
/// <param name="source">The source <see cref="JToken"/> to test.</param>
/// <param name="schema">The schema to test with.</param>
public static void Validate(this JToken source, JsonSchema schema)
{
source.Validate(schema, null);
}
/// <summary>
/// Validates the specified <see cref="JToken"/>.
/// </summary>
/// <param name="source">The source <see cref="JToken"/> to test.</param>
/// <param name="schema">The schema to test with.</param>
/// <param name="validationEventHandler">The validation event handler.</param>
public static void Validate(this JToken source, JsonSchema schema, ValidationEventHandler validationEventHandler)
{
ValidationUtils.ArgumentNotNull(source, "source");
+150
View File
@@ -35,35 +35,145 @@ using System.Globalization;
namespace Newtonsoft.Json.Schema
{
/// <summary>
/// An in-memory representation of a JSON Schema.
/// </summary>
public class JsonSchema
{
/// <summary>
/// Gets or sets the id.
/// </summary>
public string Id { get; set; }
/// <summary>
/// Gets or sets the title.
/// </summary>
public string Title { get; set; }
/// <summary>
/// Gets or sets whether the object is optional.
/// </summary>
public bool? Optional { get; set; }
/// <summary>
/// Gets or sets whether the object is read only.
/// </summary>
public bool? ReadOnly { get; set; }
/// <summary>
/// Gets or sets whether the object is visible to users.
/// </summary>
public bool? Hidden { get; set; }
/// <summary>
/// Gets or sets whether the object is transient.
/// </summary>
public bool? Transient { get; set; }
/// <summary>
/// Gets or sets the description of the object.
/// </summary>
public string Description { get; set; }
/// <summary>
/// Gets or sets the types of values allowed by the object.
/// </summary>
/// <value>The type.</value>
public JsonSchemaType? Type { get; set; }
/// <summary>
/// Gets or sets the pattern.
/// </summary>
/// <value>The pattern.</value>
public string Pattern { get; set; }
/// <summary>
/// Gets or sets the minimum length.
/// </summary>
/// <value>The minimum length.</value>
public int? MinimumLength { get; set; }
/// <summary>
/// Gets or sets the maximum length.
/// </summary>
/// <value>The maximum length.</value>
public int? MaximumLength { get; set; }
/// <summary>
/// Gets or sets the maximum decimals.
/// </summary>
/// <value>The maximum decimals.</value>
public int? MaximumDecimals { get; set; }
/// <summary>
/// Gets or sets the minimum.
/// </summary>
/// <value>The minimum.</value>
public double? Minimum { get; set; }
/// <summary>
/// Gets or sets the maximum.
/// </summary>
/// <value>The maximum.</value>
public double? Maximum { get; set; }
/// <summary>
/// Gets or sets the minimum number of items.
/// </summary>
/// <value>The minimum number of items.</value>
public int? MinimumItems { get; set; }
/// <summary>
/// Gets or sets the maximum number of items.
/// </summary>
/// <value>The maximum number of items.</value>
public int? MaximumItems { get; set; }
/// <summary>
/// Gets or sets the <see cref="JsonSchema"/> of items.
/// </summary>
/// <value>The <see cref="JsonSchema"/> of items.</value>
public IList<JsonSchema> Items { get; set; }
/// <summary>
/// Gets or sets the <see cref="JsonSchema"/> of properties.
/// </summary>
/// <value>The <see cref="JsonSchema"/> of properties.</value>
public IDictionary<string, JsonSchema> Properties { get; set; }
/// <summary>
/// Gets or sets the <see cref="JsonSchema"/> of additional properties.
/// </summary>
/// <value>The <see cref="JsonSchema"/> of additional properties.</value>
public JsonSchema AdditionalProperties { get; set; }
/// <summary>
/// Gets or sets a value indicating whether additional properties are allowed.
/// </summary>
/// <value>
/// <c>true</c> if additional properties are allowed; otherwise, <c>false</c>.
/// </value>
public bool AllowAdditionalProperties { get; set; }
/// <summary>
/// Gets or sets the required property if this property is present.
/// </summary>
/// <value>The required property if this property is present.</value>
public string Requires { get; set; }
/// <summary>
/// Gets or sets the identity.
/// </summary>
/// <value>The identity.</value>
public IList<string> Identity { get; set; }
/// <summary>
/// Gets or sets the a collection of valid enum values allowed.
/// </summary>
/// <value>A collection of valid enum values allowed.</value>
public IList<JToken> Enum { get; set; }
/// <summary>
/// Gets or sets a collection of options.
/// </summary>
/// <value>A collection of options.</value>
public IDictionary<JToken, string> Options { get; set; }
/// <summary>
/// Gets or sets disallowed types.
/// </summary>
/// <value>The disallow types.</value>
public JsonSchemaType? Disallow { get; set; }
/// <summary>
/// Gets or sets the default value.
/// </summary>
/// <value>The default value.</value>
public JToken Default { get; set; }
/// <summary>
/// Gets or sets the extend <see cref="JsonSchema"/>.
/// </summary>
/// <value>The extended <see cref="JsonSchema"/>.</value>
public JsonSchema Extends { get; set; }
/// <summary>
/// Gets or sets the format.
/// </summary>
/// <value>The format.</value>
public string Format { get; set; }
private readonly string _internalId = Guid.NewGuid().ToString("N");
@@ -73,16 +183,30 @@ namespace Newtonsoft.Json.Schema
get { return _internalId; }
}
/// <summary>
/// Initializes a new instance of the <see cref="JsonSchema"/> class.
/// </summary>
public JsonSchema()
{
AllowAdditionalProperties = true;
}
/// <summary>
/// Reads a <see cref="JsonSchema"/> from the specified <see cref="JsonReader"/>.
/// </summary>
/// <param name="reader">The <see cref="JsonReader"/> containing the JSON Schema to read.</param>
/// <returns>The <see cref="JsonSchema"/> object representing the JSON Schema.</returns>
public static JsonSchema Read(JsonReader reader)
{
return Read(reader, new JsonSchemaResolver());
}
/// <summary>
/// Reads a <see cref="JsonSchema"/> from the specified <see cref="JsonReader"/>.
/// </summary>
/// <param name="reader">The <see cref="JsonReader"/> containing the JSON Schema to read.</param>
/// <param name="resolver">The <see cref="JsonSchemaResolver"/> to use when resolving schema references.</param>
/// <returns>The <see cref="JsonSchema"/> object representing the JSON Schema.</returns>
public static JsonSchema Read(JsonReader reader, JsonSchemaResolver resolver)
{
ValidationUtils.ArgumentNotNull(reader, "reader");
@@ -92,11 +216,22 @@ namespace Newtonsoft.Json.Schema
return builder.Parse(reader);
}
/// <summary>
/// Load a <see cref="JsonSchema"/> from a string that contains schema JSON.
/// </summary>
/// <param name="json">A <see cref="String"/> that contains JSON.</param>
/// <returns>A <see cref="JsonSchema"/> populated from the string that contains JSON.</returns>
public static JsonSchema Parse(string json)
{
return Parse(json, new JsonSchemaResolver());
}
/// <summary>
/// Parses the specified json.
/// </summary>
/// <param name="json">The json.</param>
/// <param name="resolver">The resolver.</param>
/// <returns></returns>
public static JsonSchema Parse(string json, JsonSchemaResolver resolver)
{
ValidationUtils.ArgumentNotNull(json, "json");
@@ -106,11 +241,20 @@ namespace Newtonsoft.Json.Schema
return Read(reader, resolver);
}
/// <summary>
/// Writes this schema to a <see cref="JsonWriter"/>.
/// </summary>
/// <param name="writer">A <see cref="JsonWriter"/> into which this method will write.</param>
public void WriteTo(JsonWriter writer)
{
WriteTo(writer, new JsonSchemaResolver());
}
/// <summary>
/// Writes this schema to a <see cref="JsonWriter"/> using the specified <see cref="JsonSchemaResolver"/>.
/// </summary>
/// <param name="writer">A <see cref="JsonWriter"/> into which this method will write.</param>
/// <param name="resolver">The resolver used.</param>
public void WriteTo(JsonWriter writer, JsonSchemaResolver resolver)
{
ValidationUtils.ArgumentNotNull(writer, "writer");
@@ -120,6 +264,12 @@ namespace Newtonsoft.Json.Schema
schemaWriter.WriteSchema(this);
}
/// <summary>
/// Returns a <see cref="T:System.String"/> that represents the current <see cref="T:System.Object"/>.
/// </summary>
/// <returns>
/// A <see cref="T:System.String"/> that represents the current <see cref="T:System.Object"/>.
/// </returns>
public override string ToString()
{
StringWriter writer = new StringWriter(CultureInfo.InvariantCulture);
@@ -32,7 +32,17 @@ namespace Newtonsoft.Json.Schema
/// </summary>
public class JsonSchemaException : Exception
{
/// <summary>
/// Gets the line number indicating where the error occurred.
/// </summary>
/// <value>The line number indicating where the error occurred.</value>
public int LineNumber { get; private set; }
/// <summary>
/// Gets the line position indicating where the error occurred.
/// </summary>
/// <value>The line position indicating where the error occurred.</value>
public int LinePosition { get; private set; }
/// <summary>
@@ -34,9 +34,19 @@ using Newtonsoft.Json.Serialization;
namespace Newtonsoft.Json.Schema
{
/// <summary>
/// Generates a <see cref="JsonSchema"/> from a specified <see cref="Type"/>.
/// </summary>
public class JsonSchemaGenerator
{
/// <summary>
/// Gets or sets how undefined schemas are handled by the serializer.
/// </summary>
public UndefinedSchemaIdHandling UndefinedSchemaIdHandling { get; set; }
/// <summary>
/// Gets or sets the mapping resolver used by the generator when
/// mapping JSON properties to .NET objet members.
/// </summary>
public IMappingResolver MappingResolver { get; set; }
private class TypeSchema
@@ -96,21 +106,45 @@ namespace Newtonsoft.Json.Schema
return popped;
}
/// <summary>
/// Generate a <see cref="JsonSchema"/> from the specified type.
/// </summary>
/// <param name="type">The type to generate a <see cref="JsonSchema"/> from.</param>
/// <returns>A <see cref="JsonSchema"/> generated from the specified type.</returns>
public JsonSchema Generate(Type type)
{
return Generate(type, new JsonSchemaResolver(), false);
}
/// <summary>
/// Generate a <see cref="JsonSchema"/> from the specified type.
/// </summary>
/// <param name="type">The type to generate a <see cref="JsonSchema"/> from.</param>
/// <param name="resolver">The <see cref="JsonSchemaResolver"/> used to resolve schema references.</param>
/// <returns>A <see cref="JsonSchema"/> generated from the specified type.</returns>
public JsonSchema Generate(Type type, JsonSchemaResolver resolver)
{
return Generate(type, resolver, false);
}
/// <summary>
/// Generate a <see cref="JsonSchema"/> from the specified type.
/// </summary>
/// <param name="type">The type to generate a <see cref="JsonSchema"/> from.</param>
/// <param name="rootSchemaNullable">Specify whether the generated root <see cref="JsonSchema"/> will be nullable.</param>
/// <returns>A <see cref="JsonSchema"/> generated from the specified type.</returns>
public JsonSchema Generate(Type type, bool rootSchemaNullable)
{
return Generate(type, new JsonSchemaResolver(), rootSchemaNullable);
}
/// <summary>
/// Generate a <see cref="JsonSchema"/> from the specified type.
/// </summary>
/// <param name="type">The type to generate a <see cref="JsonSchema"/> from.</param>
/// <param name="resolver">The <see cref="JsonSchemaResolver"/> used to resolve schema references.</param>
/// <param name="rootSchemaNullable">Specify whether the generated root <see cref="JsonSchema"/> will be nullable.</param>
/// <returns>A <see cref="JsonSchema"/> generated from the specified type.</returns>
public JsonSchema Generate(Type type, JsonSchemaResolver resolver, bool rootSchemaNullable)
{
ValidationUtils.ArgumentNotNull(type, "type");
@@ -121,7 +155,7 @@ namespace Newtonsoft.Json.Schema
return GenerateInternal(type, !rootSchemaNullable);
}
public string GetTitle(Type type)
private string GetTitle(Type type)
{
JsonContainerAttribute containerAttribute = JsonTypeReflector.GetJsonContainerAttribute(type);
@@ -131,7 +165,7 @@ namespace Newtonsoft.Json.Schema
return null;
}
public string GetDescription(Type type)
private string GetDescription(Type type)
{
JsonContainerAttribute containerAttribute = JsonTypeReflector.GetJsonContainerAttribute(type);
@@ -255,7 +289,7 @@ namespace Newtonsoft.Json.Schema
if (mapping.DefaultValue != null)
propertySchema.Default = JToken.FromObject(mapping.DefaultValue);
CurrentSchema.Properties.Add(mapping.MappingName, propertySchema);
CurrentSchema.Properties.Add(mapping.PropertyName, propertySchema);
}
}
@@ -33,15 +33,30 @@ using Newtonsoft.Json.Utilities;
namespace Newtonsoft.Json.Schema
{
/// <summary>
/// Resolves <see cref="JsonSchema"/> from an id.
/// </summary>
public class JsonSchemaResolver
{
/// <summary>
/// Gets or sets the loaded schemas.
/// </summary>
/// <value>The loaded schemas.</value>
public IList<JsonSchema> LoadedSchemas { get; protected set; }
/// <summary>
/// Initializes a new instance of the <see cref="JsonSchemaResolver"/> class.
/// </summary>
public JsonSchemaResolver()
{
LoadedSchemas = new List<JsonSchema>();
}
/// <summary>
/// Gets a <see cref="JsonSchema"/> for the specified id.
/// </summary>
/// <param name="id">The id.</param>
/// <returns>A <see cref="JsonSchema"/> for the specified id.</returns>
public virtual JsonSchema GetSchema(string id)
{
JsonSchema schema = LoadedSchemas.SingleOrDefault(s => s.Id == id);
@@ -30,17 +30,47 @@ using System.Text;
namespace Newtonsoft.Json.Schema
{
/// <summary>
/// The value types allowed by the <see cref="JsonSchema"/>.
/// </summary>
[Flags]
public enum JsonSchemaType
{
/// <summary>
/// No type specified.
/// </summary>
None = 0,
/// <summary>
/// String type.
/// </summary>
String = 1,
/// <summary>
/// Float type.
/// </summary>
Float = 2,
/// <summary>
/// Integer type.
/// </summary>
Integer = 4,
/// <summary>
/// Boolean type.
/// </summary>
Boolean = 8,
/// <summary>
/// Object type.
/// </summary>
Object = 16,
/// <summary>
/// Array type.
/// </summary>
Array = 32,
/// <summary>
/// Null type.
/// </summary>
Null = 64,
/// <summary>
/// Any type.
/// </summary>
Any = String | Float | Integer | Boolean | Object | Array | Null
}
}
@@ -25,10 +25,22 @@
namespace Newtonsoft.Json.Schema
{
/// <summary>
/// Specifies undefined schema Id handling options for the <see cref="JsonSchemaGenerator"/>.
/// </summary>
public enum UndefinedSchemaIdHandling
{
/// <summary>
/// Do not infer a schema Id.
/// </summary>
None = 0,
/// <summary>
/// Use the .NET type name as the schema Id.
/// </summary>
UseTypeName = 1,
/// <summary>
/// Use the assembly qualified .NET type name as the schema Id.
/// </summary>
UseAssemblyQualifiedName = 2,
}
}
@@ -28,6 +28,9 @@ using Newtonsoft.Json.Utilities;
namespace Newtonsoft.Json.Schema
{
/// <summary>
/// Returns detailed information related to the <see cref="ValidationEventHandler"/>.
/// </summary>
public class ValidationEventArgs : EventArgs
{
private readonly JsonSchemaException _ex;
@@ -38,11 +41,19 @@ namespace Newtonsoft.Json.Schema
_ex = ex;
}
/// <summary>
/// Gets the <see cref="JsonSchemaException"/> associated with the validation event.
/// </summary>
/// <value>The JsonSchemaException associated with the validation event.</value>
public JsonSchemaException Exception
{
get { return _ex; }
}
/// <summary>
/// Gets the text description corresponding to the validation event.
/// </summary>
/// <value>The text description.</value>
public string Message
{
get { return _ex.Message; }
@@ -25,5 +25,8 @@
namespace Newtonsoft.Json.Schema
{
/// <summary>
/// Represents the callback method that will handle JSON schema validation events and the <see cref="ValidationEventArgs"/>.
/// </summary>
public delegate void ValidationEventHandler(object sender, ValidationEventArgs e);
}
@@ -27,23 +27,32 @@ using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Globalization;
namespace Newtonsoft.Json.Serialization
{
/// <summary>
/// Resolves member mappings for a type, camel casing property names.
/// </summary>
public class CamelCaseMappingResolver : DefaultMappingResolver
{
protected override string ResolveMappingName(string mappedName)
/// <summary>
/// Resolves the name of the property.
/// </summary>
/// <param name="propertyName">Name of the property.</param>
/// <returns></returns>
protected override string ResolvePropertyName(string propertyName)
{
// lower case the first letter of the passed in name
if (string.IsNullOrEmpty(mappedName))
return mappedName;
if (string.IsNullOrEmpty(propertyName))
return propertyName;
if (!char.IsUpper(mappedName[0]))
return mappedName;
if (!char.IsUpper(propertyName[0]))
return propertyName;
string camelCaseName = char.ToLower(mappedName[0]).ToString();
if (mappedName.Length > 1)
camelCaseName += mappedName.Substring(1);
string camelCaseName = char.ToLower(propertyName[0], CultureInfo.InvariantCulture).ToString(CultureInfo.InvariantCulture);
if (propertyName.Length > 1)
camelCaseName += propertyName.Substring(1);
return camelCaseName;
}
@@ -26,47 +26,66 @@
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Reflection;
using System.Runtime.Serialization;
using System.Text;
using Newtonsoft.Json.Utilities;
namespace Newtonsoft.Json.Serialization
{
/// <summary>
/// Resolves member mappings for a type.
/// </summary>
public class DefaultMappingResolver : IMappingResolver
{
internal static readonly IMappingResolver Instance = new DefaultMappingResolver();
private readonly Dictionary<Type, JsonMemberMappingCollection> TypeMemberMappingsCache = new Dictionary<Type, JsonMemberMappingCollection>();
private readonly Dictionary<Type, JsonMemberMappingCollection> _typeMemberMappingsCache = new Dictionary<Type, JsonMemberMappingCollection>();
/// <summary>
/// Gets or sets the default members search flags.
/// </summary>
/// <value>The default members search flags.</value>
public BindingFlags DefaultMembersSearchFlags { get; set; }
/// <summary>
/// Initializes a new instance of the <see cref="DefaultMappingResolver"/> class.
/// </summary>
public DefaultMappingResolver()
{
DefaultMembersSearchFlags = BindingFlags.Public | BindingFlags.Instance;
}
/// <summary>
/// Returns a collection of <see cref="JsonMemberMapping"/> for the specified <see cref="Type"/>
/// to be used during serialization.
/// </summary>
/// <param name="type">The type to be resolved.</param>
/// <returns>A collection of <see cref="JsonMemberMapping"/> to be used during serialization.</returns>
public virtual JsonMemberMappingCollection ResolveMappings(Type type)
{
JsonMemberMappingCollection memberMappings;
if (TypeMemberMappingsCache.TryGetValue(type, out memberMappings))
if (_typeMemberMappingsCache.TryGetValue(type, out memberMappings))
return memberMappings;
// double check locking to avoid threading issues
lock (TypeMemberMappingsCache)
lock (_typeMemberMappingsCache)
{
if (TypeMemberMappingsCache.TryGetValue(type, out memberMappings))
if (_typeMemberMappingsCache.TryGetValue(type, out memberMappings))
return memberMappings;
memberMappings = CreateMemberMappings(type);
TypeMemberMappingsCache[type] = memberMappings;
_typeMemberMappingsCache[type] = memberMappings;
return memberMappings;
}
}
/// <summary>
/// Gets the serializable members for the type.
/// </summary>
/// <param name="objectType">The type to get serializable members for.</param>
/// <returns>The serializable members for the type.</returns>
protected virtual List<MemberInfo> GetSerializableMembers(Type objectType)
{
#if !PocketPC
@@ -118,6 +137,12 @@ namespace Newtonsoft.Json.Serialization
return memberMappings;
}
/// <summary>
/// Creates a <see cref="JsonMemberMapping"/> for the given <see cref="MemberInfo"/>.
/// </summary>
/// <param name="memberSerialization">The member's declaring type member serialization mode.</param>
/// <param name="member">The member to create a <see cref="JsonMemberMapping"/> for.</param>
/// <returns>A created <see cref="JsonMemberMapping"/> for the given <see cref="MemberInfo"/>.</returns>
protected virtual JsonMemberMapping CreateMemberMapping(MemberSerialization memberSerialization, MemberInfo member)
{
JsonObjectAttribute jsonObjectAttribute = JsonTypeReflector.GetJsonContainerAttribute(member.DeclaringType) as JsonObjectAttribute;
@@ -145,7 +170,7 @@ namespace Newtonsoft.Json.Serialization
else
mappedName = member.Name;
string resolvedMappedName = ResolveMappingName(mappedName);
string resolvedMappedName = ResolvePropertyName(mappedName);
bool required;
if (propertyAttribute != null)
@@ -186,9 +211,14 @@ namespace Newtonsoft.Json.Serialization
return new JsonMemberMapping(resolvedMappedName, member, ignored, readable, writable, memberConverter, defaultValue, required, isReference, nullValueHandling, defaultValueHandling, referenceLoopHandling);
}
protected virtual string ResolveMappingName(string mappedName)
/// <summary>
/// Resolves the name of the property.
/// </summary>
/// <param name="propertyName">Name of the property.</param>
/// <returns></returns>
protected virtual string ResolvePropertyName(string propertyName)
{
return mappedName;
return propertyName;
}
}
}
@@ -1,4 +1,4 @@
#region License
#region License
// Copyright (c) 2007 James Newton-King
//
// Permission is hereby granted, free of charge, to any person
@@ -48,14 +48,14 @@ namespace Newtonsoft.Json.Serialization
}
}
public object ResolveObject(string reference)
public object ResolveReference(string reference)
{
object value;
Mappings.TryGetByFirst(reference, out value);
return value;
}
public string ResolveReference(object value)
public string GetReference(object value)
{
string reference;
if (!Mappings.TryGetBySecond(value, out reference))
@@ -68,12 +68,12 @@ namespace Newtonsoft.Json.Serialization
return reference;
}
public void AddObjectReference(string reference, object value)
public void AddReference(string reference, object value)
{
Mappings.Add(reference, value);
}
public bool HasObjectReference(object value)
public bool IsReferenced(object value)
{
string reference;
return Mappings.TryGetBySecond(value, out reference);
@@ -0,0 +1,44 @@
using System;
using System.Runtime.Serialization;
using System.Reflection;
using System.Globalization;
using Newtonsoft.Json.Utilities;
namespace Newtonsoft.Json.Serialization
{
/// <summary>
/// The default serialization binder used when resolving and loading classes from type names.
/// </summary>
public class DefaultSerializationBinder : SerializationBinder
{
internal static readonly DefaultSerializationBinder Instance = new DefaultSerializationBinder();
/// <summary>
/// When overridden in a derived class, controls the binding of a serialized object to a type.
/// </summary>
/// <param name="assemblyName">Specifies the <see cref="T:System.Reflection.Assembly"/> name of the serialized object.</param>
/// <param name="typeName">Specifies the <see cref="T:System.Type"/> name of the serialized object.</param>
/// <returns>
/// The type of the object the formatter creates a new instance of.
/// </returns>
public override Type BindToType(string assemblyName, string typeName)
{
if (assemblyName != null)
{
Assembly assembly = Assembly.Load(assemblyName);
if (assembly == null)
throw new JsonSerializationException("Could not load assembly '{0}'.".FormatWith(CultureInfo.InvariantCulture, assemblyName));
Type type = assembly.GetType(typeName);
if (type == null)
throw new JsonSerializationException("Could not find type '{0}'.".FormatWith(CultureInfo.InvariantCulture, typeName));
return type;
}
else
{
return Type.GetType(typeName);
}
}
}
}
@@ -37,7 +37,7 @@ namespace Newtonsoft.Json.Serialization
{
/// <summary>
/// Returns a collection of <see cref="JsonMemberMapping"/> for the specified <see cref="Type"/>
/// to be used during serialization.</see>
/// to be used during serialization.
/// </summary>
/// <param name="type">The type to be resolved.</param>
/// <returns>A collection of <see cref="JsonMemberMapping"/> to be used during serialization.</returns>
@@ -25,11 +25,36 @@
namespace Newtonsoft.Json.Serialization
{
/// <summary>
/// Used to resolve references when serializing and deserializing JSON by the <see cref="JsonSerializer"/>.
/// </summary>
public interface IReferenceResolver
{
object ResolveObject(string reference);
string ResolveReference(object value);
bool HasObjectReference(object value);
void AddObjectReference(string reference, object value);
/// <summary>
/// Resolves the reference to its object.
/// </summary>
/// <param name="reference">The reference to resolve.</param>
/// <returns>The object that</returns>
object ResolveReference(string reference);
/// <summary>
/// Gets the reference for the sepecified object.
/// </summary>
/// <param name="value">The object to get a reference for.</param>
/// <returns>The reference to the object.</returns>
string GetReference(object value);
/// <summary>
/// Determines whether the specified object is referenced.
/// </summary>
/// <param name="value">The object to test for a reference.</param>
/// <returns>
/// <c>true</c> if the specified object is referenced; otherwise, <c>false</c>.
/// </returns>
bool IsReferenced(object value);
/// <summary>
/// Adds a reference to the specified object.
/// </summary>
/// <param name="reference">The reference.</param>
/// <param name="value">The object to reference.</param>
void AddReference(string reference, object value);
}
}
@@ -23,16 +23,16 @@
// OTHER DEALINGS IN THE SOFTWARE.
#endregion
using System;
using System.Collections.Generic;
using System.Text;
using System.Reflection;
namespace Newtonsoft.Json.Serialization
{
/// <summary>
/// Maps a JSON property to a .NET member.
/// </summary>
public class JsonMemberMapping
{
private readonly string _mappingName;
private readonly string _propertyName;
private readonly MemberInfo _member;
private readonly bool _ignored;
private readonly bool _readable;
@@ -45,9 +45,24 @@ namespace Newtonsoft.Json.Serialization
private readonly DefaultValueHandling? _defaultValueHandling;
private readonly ReferenceLoopHandling? _referenceLoopHandling;
public JsonMemberMapping(string mappingName, MemberInfo member, bool ignored, bool readable, bool writable, JsonConverter memberConverter, object defaultValue, bool required, bool isReference, NullValueHandling? nullValueHandling, DefaultValueHandling? defaultValueHandling, ReferenceLoopHandling? referenceLoopHandling)
/// <summary>
/// Initializes a new instance of the <see cref="JsonMemberMapping"/> class.
/// </summary>
/// <param name="propertyName">Name of the property.</param>
/// <param name="member">The member.</param>
/// <param name="ignored">If set to <c>true</c> mapping is ignored during serialization.</param>
/// <param name="readable">If set to <c>true</c> mapping is readable.</param>
/// <param name="writable">If set to <c>true</c> mapping is writable.</param>
/// <param name="memberConverter">The member converter to use during serialization.</param>
/// <param name="defaultValue">The mapping default value.</param>
/// <param name="required">If set to <c>true</c> mapping is required during serialization.</param>
/// <param name="isReference">If set to <c>true</c> mapping preserve reference.</param>
/// <param name="nullValueHandling">Mapping null value handling.</param>
/// <param name="defaultValueHandling">Mapping default value handling.</param>
/// <param name="referenceLoopHandling">Mapping reference loop handling.</param>
public JsonMemberMapping(string propertyName, MemberInfo member, bool ignored, bool readable, bool writable, JsonConverter memberConverter, object defaultValue, bool required, bool isReference, NullValueHandling? nullValueHandling, DefaultValueHandling? defaultValueHandling, ReferenceLoopHandling? referenceLoopHandling)
{
_mappingName = mappingName;
_propertyName = propertyName;
_member = member;
_ignored = ignored;
_readable = readable;
@@ -61,61 +76,111 @@ namespace Newtonsoft.Json.Serialization
_referenceLoopHandling = referenceLoopHandling;
}
public string MappingName
/// <summary>
/// Gets the name of the property.
/// </summary>
/// <value>The name of the property.</value>
public string PropertyName
{
get { return _mappingName; }
get { return _propertyName; }
}
/// <summary>
/// Gets the member.
/// </summary>
/// <value>The member.</value>
public MemberInfo Member
{
get { return _member; }
}
/// <summary>
/// Gets a value indicating whether this <see cref="JsonMemberMapping"/> is ignored.
/// </summary>
/// <value><c>true</c> if ignored; otherwise, <c>false</c>.</value>
public bool Ignored
{
get { return _ignored; }
}
/// <summary>
/// Gets a value indicating whether this <see cref="JsonMemberMapping"/> is readable.
/// </summary>
/// <value><c>true</c> if readable; otherwise, <c>false</c>.</value>
public bool Readable
{
get { return _readable; }
}
/// <summary>
/// Gets a value indicating whether this <see cref="JsonMemberMapping"/> is writable.
/// </summary>
/// <value><c>true</c> if writable; otherwise, <c>false</c>.</value>
public bool Writable
{
get { return _writable; }
}
/// <summary>
/// Gets the member converter.
/// </summary>
/// <value>The member converter.</value>
public JsonConverter MemberConverter
{
get { return _memberConverter; }
}
/// <summary>
/// Gets the default value.
/// </summary>
/// <value>The default value.</value>
public object DefaultValue
{
get { return _defaultValue; }
}
/// <summary>
/// Gets a value indicating whether this <see cref="JsonMemberMapping"/> is required.
/// </summary>
/// <value><c>true</c> if required; otherwise, <c>false</c>.</value>
public bool Required
{
get { return _required; }
}
/// <summary>
/// Gets a value indicating whether this mapping preserves object references.
/// </summary>
/// <value>
/// <c>true</c> if this instance is reference; otherwise, <c>false</c>.
/// </value>
public bool IsReference
{
get { return _isReference; }
}
/// <summary>
/// Gets the mapping null value handling.
/// </summary>
/// <value>The null value handling.</value>
public NullValueHandling? NullValueHandling
{
get { return _nullValueHandling; }
}
/// <summary>
/// Gets the mapping default value handling.
/// </summary>
/// <value>The default value handling.</value>
public DefaultValueHandling? DefaultValueHandling
{
get { return _defaultValueHandling; }
}
/// <summary>
/// Gets the mapping reference loop handling.
/// </summary>
/// <value>The reference loop handling.</value>
public ReferenceLoopHandling? ReferenceLoopHandling
{
get { return _referenceLoopHandling; }
@@ -32,27 +32,39 @@ using System.Globalization;
namespace Newtonsoft.Json.Serialization
{
/// <summary>
/// A collection of <see cref="JsonMemberMapping"/> objects.
/// </summary>
public class JsonMemberMappingCollection : KeyedCollection<string, JsonMemberMapping>
{
/// <summary>
/// When implemented in a derived class, extracts the key from the specified element.
/// </summary>
/// <param name="item">The element from which to extract the key.</param>
/// <returns>The key for the specified element.</returns>
protected override string GetKeyForItem(JsonMemberMapping item)
{
return item.MappingName;
return item.PropertyName;
}
/// <summary>
/// Adds a <see cref="JsonMemberMapping"/> object.
/// </summary>
/// <param name="memberMapping">The member mapping to add to the collection.</param>
public void AddMapping(JsonMemberMapping memberMapping)
{
if (Contains(memberMapping.MappingName))
if (Contains(memberMapping.PropertyName))
{
// don't overwrite existing mapping with ignored mapping
if (memberMapping.Ignored)
return;
JsonMemberMapping existingMemberMapping = this[memberMapping.MappingName];
JsonMemberMapping existingMemberMapping = this[memberMapping.PropertyName];
if (!existingMemberMapping.Ignored)
{
throw new JsonSerializationException(
"A member with the name '{0}' already exists on {1}. Use the JsonPropertyAttribute to specify another name.".FormatWith(CultureInfo.InvariantCulture, memberMapping.MappingName, memberMapping.Member.DeclaringType));
"A member with the name '{0}' already exists on {1}. Use the JsonPropertyAttribute to specify another name.".FormatWith(CultureInfo.InvariantCulture, memberMapping.PropertyName, memberMapping.Member.DeclaringType));
}
else
{
@@ -64,21 +76,36 @@ namespace Newtonsoft.Json.Serialization
Add(memberMapping);
}
public bool TryGetClosestMatchMapping(string mappingName, out JsonMemberMapping memberMapping)
/// <summary>
/// Tries to get the closest matching <see cref="JsonMemberMapping"/> object.
/// First attempts to get an exact case match of propertyName and then
/// a case insensitive match.
/// </summary>
/// <param name="propertyName">Name of the mapping.</param>
/// <param name="memberMapping">The member mapping.</param>
/// <returns></returns>
public bool TryGetClosestMatchMapping(string propertyName, out JsonMemberMapping memberMapping)
{
if (TryGetMapping(mappingName, StringComparison.Ordinal, out memberMapping))
if (TryGetMapping(propertyName, StringComparison.Ordinal, out memberMapping))
return true;
if (TryGetMapping(mappingName, StringComparison.OrdinalIgnoreCase, out memberMapping))
if (TryGetMapping(propertyName, StringComparison.OrdinalIgnoreCase, out memberMapping))
return true;
return false;
}
public bool TryGetMapping(string mappingName, StringComparison comparisonType, out JsonMemberMapping memberMapping)
/// <summary>
/// Tries to get a member mapping by property name.
/// </summary>
/// <param name="propertyName">The property name of the member mapping to get.</param>
/// <param name="comparisonType">Type property name compare string comparison.</param>
/// <param name="memberMapping">The member mapping.</param>
/// <returns></returns>
public bool TryGetMapping(string propertyName, StringComparison comparisonType, out JsonMemberMapping memberMapping)
{
foreach (JsonMemberMapping mapping in this)
{
if (string.Compare(mappingName, mapping.MappingName, comparisonType) == 0)
if (string.Compare(propertyName, mapping.PropertyName, comparisonType) == 0)
{
memberMapping = mapping;
return true;
@@ -25,6 +25,7 @@
using System;
using Newtonsoft.Json.Utilities;
using System.Runtime.Serialization;
namespace Newtonsoft.Json.Serialization
{
@@ -87,6 +88,18 @@ namespace Newtonsoft.Json.Serialization
set { _serializer.PreserveReferencesHandling = value; }
}
public override TypeNameHandling TypeNameHandling
{
get { return _serializer.TypeNameHandling; }
set { _serializer.TypeNameHandling = value; }
}
public override SerializationBinder Binder
{
get { return _serializer.Binder; }
set { _serializer.Binder = value; }
}
public JsonSerializerProxy(JsonSerializerReader serializerReader)
{
ValidationUtils.ArgumentNotNull(serializerReader, "serializerReader");
@@ -62,13 +62,20 @@ namespace Newtonsoft.Json.Serialization
}
else if (reader.TokenType == JsonToken.StartObject)
{
if (!reader.Read())
throw new JsonSerializationException("Unexpected end when deserializing object.");
CheckedRead(reader);
string id = null;
if (reader.TokenType == JsonToken.PropertyName && string.Equals(reader.Value.ToString(), JsonTypeReflector.IdPropertyName, StringComparison.Ordinal))
{
CheckedRead(reader);
id = reader.Value.ToString();
CheckedRead(reader);
}
if (CollectionUtils.IsDictionaryType(objectType))
PopulateDictionary(CollectionUtils.CreateDictionaryWrapper(target), reader);
PopulateDictionary(CollectionUtils.CreateDictionaryWrapper(target), reader, id);
else
PopulateObject(target, reader, objectType);
PopulateObject(target, reader, objectType, id);
}
}
@@ -80,10 +87,7 @@ namespace Newtonsoft.Json.Serialization
if (!reader.Read())
return null;
if (objectType != null)
return CreateValue(reader, objectType, null, null);
else
return CreateJToken(reader);
return CreateValue(reader, objectType, null, null);
}
private JsonSerializerProxy GetInternalSerializer()
@@ -96,6 +100,8 @@ namespace Newtonsoft.Json.Serialization
private JToken CreateJToken(JsonReader reader)
{
ValidationUtils.ArgumentNotNull(reader, "reader");
JToken token;
using (JTokenWriter writer = new JTokenWriter())
{
@@ -106,6 +112,28 @@ namespace Newtonsoft.Json.Serialization
return token;
}
private JToken CreateJObject(JsonReader reader)
{
ValidationUtils.ArgumentNotNull(reader, "reader");
// throw new Exception("Expected current token of type {0}, got {1}.".FormatWith(CultureInfo.InvariantCulture, JsonToken.PropertyName, reader.TokenType));
JToken token;
using (JTokenWriter writer = new JTokenWriter())
{
writer.WriteStartObject();
if (reader.TokenType == JsonToken.PropertyName)
writer.WriteToken(reader, reader.Depth - 1);
else
writer.WriteEndObject();
token = writer.Token;
}
return token;
}
private object CreateValue(JsonReader reader, Type objectType, object existingValue, JsonConverter memberConverter)
{
object value;
@@ -134,47 +162,111 @@ namespace Newtonsoft.Json.Serialization
// populate a typed object or generic dictionary/array
// depending upon whether an objectType was supplied
case JsonToken.StartObject:
if (objectType == null)
{
value = CreateJToken(reader);
}
else
{
CheckedRead(reader);
CheckedRead(reader);
if (reader.TokenType == JsonToken.PropertyName)
string id = null;
if (reader.TokenType == JsonToken.PropertyName)
{
bool specialProperty;
do
{
string propertyName = reader.Value.ToString();
if (string.Equals(propertyName, JsonTypeReflector.RefPropertyName, StringComparison.Ordinal))
{
CheckedRead(reader);
string id = reader.Value.ToString();
string reference = reader.Value.ToString();
CheckedRead(reader);
return _serializer.ReferenceResolver.ResolveObject(id);
return _serializer.ReferenceResolver.ResolveReference(reference);
}
else if (string.Equals(propertyName, JsonTypeReflector.IdPropertyName, StringComparison.Ordinal)
&& !CollectionUtils.IsDictionaryType(objectType)
&& CollectionUtils.IsListType(objectType))
else if (string.Equals(propertyName, JsonTypeReflector.TypePropertyName, StringComparison.Ordinal))
{
return CreateReferencedList(reader, objectType, existingValue);
}
}
CheckedRead(reader);
string qualifiedTypeName = reader.Value.ToString();
CheckedRead(reader);
if (_serializer.TypeNameHandling != TypeNameHandling.None)
{
int delimiterIndex = qualifiedTypeName.IndexOf(',');
string typeName;
string assemblyName;
if (delimiterIndex != -1)
{
typeName = qualifiedTypeName.Substring(0, delimiterIndex).Trim();
assemblyName = qualifiedTypeName.Substring(delimiterIndex + 1, qualifiedTypeName.Length - delimiterIndex - 1).Trim();
}
else
{
typeName = qualifiedTypeName;
assemblyName = null;
}
Type specifiedType;
try
{
specifiedType = _serializer.Binder.BindToType(assemblyName, typeName);
}
catch (Exception ex)
{
throw new JsonSerializationException("Error resolving type specified in JSON '{0}'.".FormatWith(CultureInfo.InvariantCulture, qualifiedTypeName), ex);
}
if (specifiedType == null)
throw new JsonSerializationException("Type specified in JSON '{0}' was not resolved.".FormatWith(CultureInfo.InvariantCulture, qualifiedTypeName));
if (objectType != null && !objectType.IsAssignableFrom(specifiedType))
throw new JsonSerializationException("Type specified in JSON '{0}' is not compatible with '{1}'.".FormatWith(CultureInfo.InvariantCulture, specifiedType.AssemblyQualifiedName, objectType.AssemblyQualifiedName));
objectType = specifiedType;
}
specialProperty = true;
}
else if (string.Equals(propertyName, JsonTypeReflector.IdPropertyName, StringComparison.Ordinal))
{
CheckedRead(reader);
id = reader.Value.ToString();
CheckedRead(reader);
specialProperty = true;
}
else if (string.Equals(propertyName, JsonTypeReflector.ArrayValuesPropertyName, StringComparison.Ordinal))
{
CheckedRead(reader);
object list = CreateList(reader, objectType, existingValue, id);
CheckedRead(reader);
return list;
}
else
{
specialProperty = false;
}
} while (specialProperty
&& reader.TokenType == JsonToken.PropertyName);
}
if (objectType == null)
{
value = CreateJObject(reader);
}
else
{
if (CollectionUtils.IsDictionaryType(objectType))
{
if (existingValue == null)
value = CreateAndPopulateDictionary(reader, objectType);
value = CreateAndPopulateDictionary(reader, objectType, id);
else
value = PopulateDictionary(CollectionUtils.CreateDictionaryWrapper(existingValue), reader);
value = PopulateDictionary(CollectionUtils.CreateDictionaryWrapper(existingValue), reader, id);
}
else
{
if (existingValue == null)
value = CreateAndPopulateObject(reader, objectType);
value = CreateAndPopulateObject(reader, objectType, id);
else
value = PopulateObject(existingValue, reader, objectType);
value = PopulateObject(existingValue, reader, objectType, id);
}
}
break;
@@ -215,27 +307,6 @@ namespace Newtonsoft.Json.Serialization
throw new JsonSerializationException("Unexpected end when deserializing object.");
}
private object CreateReferencedList(JsonReader reader, Type objectType, object existingValue)
{
object value;
CheckedRead(reader);
string id = reader.Value.ToString();
CheckedRead(reader);
if (reader.TokenType != JsonToken.PropertyName && reader.Value.ToString() != "value")
throw new JsonSerializationException("Error reading referenced list.");
CheckedRead(reader);
if (reader.TokenType != JsonToken.StartArray)
throw new JsonSerializationException("Error reading referenced list.");
value = CreateList(reader, objectType, existingValue, id);
CheckedRead(reader);
return value;
}
private object CreateList(JsonReader reader, Type objectType, object existingValue, string reference)
{
object value;
@@ -344,7 +415,7 @@ namespace Newtonsoft.Json.Serialization
return true;
}
private object CreateAndPopulateDictionary(JsonReader reader, Type objectType)
private object CreateAndPopulateDictionary(JsonReader reader, Type objectType, string id)
{
if (IsTypeGenericDictionaryInterface(objectType))
{
@@ -355,34 +426,30 @@ namespace Newtonsoft.Json.Serialization
}
IWrappedDictionary dictionary = CollectionUtils.CreateDictionaryWrapper(Activator.CreateInstance(objectType));
PopulateDictionary(dictionary, reader);
PopulateDictionary(dictionary, reader, id);
return dictionary.UnderlyingDictionary;
}
private IDictionary PopulateDictionary(IWrappedDictionary dictionary, JsonReader reader)
private IDictionary PopulateDictionary(IWrappedDictionary dictionary, JsonReader reader, string id)
{
Type dictionaryType = dictionary.UnderlyingDictionary.GetType();
Type dictionaryKeyType = ReflectionUtils.GetDictionaryKeyType(dictionaryType);
Type dictionaryValueType = ReflectionUtils.GetDictionaryValueType(dictionaryType);
if (id != null)
_serializer.ReferenceResolver.AddReference(id, dictionary.UnderlyingDictionary);
do
{
switch (reader.TokenType)
{
case JsonToken.PropertyName:
if (reader.Value is string && string.Equals(reader.Value.ToString(), JsonTypeReflector.IdPropertyName, StringComparison.Ordinal))
{
reader.Read();
_serializer.ReferenceResolver.AddObjectReference(reader.Value.ToString(), dictionary.UnderlyingDictionary);
}
else
{
object keyValue = EnsureType(reader.Value, dictionaryKeyType);
reader.Read();
object keyValue = EnsureType(reader.Value, dictionaryKeyType);
CheckedRead(reader);
dictionary.Add(keyValue, CreateValue(reader, dictionaryValueType, null, null));
}
dictionary.Add(keyValue, CreateValue(reader, dictionaryValueType, null, null));
break;
case JsonToken.EndObject:
return dictionary;
@@ -414,7 +481,7 @@ namespace Newtonsoft.Json.Serialization
private IList PopulateList(IList list, Type listItemType, JsonReader reader, string reference)
{
if (reference != null)
_serializer.ReferenceResolver.AddObjectReference(reference, list);
_serializer.ReferenceResolver.AddReference(reference, list);
while (reader.Read())
{
@@ -457,7 +524,7 @@ namespace Newtonsoft.Json.Serialization
|| genericDefinition == typeof(IEnumerable<>));
}
private object CreateAndPopulateObject(JsonReader reader, Type objectType)
private object CreateAndPopulateObject(JsonReader reader, Type objectType, string id)
{
object newObject;
@@ -468,7 +535,7 @@ namespace Newtonsoft.Json.Serialization
{
newObject = Activator.CreateInstance(objectType);
PopulateObject(newObject, reader, objectType);
PopulateObject(newObject, reader, objectType, id);
return newObject;
}
@@ -529,7 +596,7 @@ namespace Newtonsoft.Json.Serialization
foreach (KeyValuePair<JsonMemberMapping, object> mappingValue in mappingValues)
{
ParameterInfo matchingConstructorParameter = constructorParameters.ForgivingCaseSensitiveFind(kv => kv.Key.Name, mappingValue.Key.MappingName).Key;
ParameterInfo matchingConstructorParameter = constructorParameters.ForgivingCaseSensitiveFind(kv => kv.Key.Name, mappingValue.Key.PropertyName).Key;
if (matchingConstructorParameter != null)
constructorParameters[matchingConstructorParameter] = mappingValue.Value;
else
@@ -548,11 +615,14 @@ namespace Newtonsoft.Json.Serialization
return createdObject;
}
private object PopulateObject(object newObject, JsonReader reader, Type objectType)
private object PopulateObject(object newObject, JsonReader reader, Type objectType, string id)
{
JsonMemberMappingCollection memberMappings = _serializer.GetMemberMappings(objectType);
Dictionary<string, bool> requiredMappings =
memberMappings.Where(m => m.Required).ToDictionary(m => m.MappingName, m => false);
memberMappings.Where(m => m.Required).ToDictionary(m => m.PropertyName, m => false);
if (id != null)
_serializer.ReferenceResolver.AddReference(id, newObject);
do
{
@@ -564,17 +634,10 @@ namespace Newtonsoft.Json.Serialization
if (!reader.Read())
throw new JsonSerializationException("Unexpected end when setting {0}'s value.".FormatWith(CultureInfo.InvariantCulture, memberName));
if (string.Equals(memberName, JsonTypeReflector.IdPropertyName, StringComparison.Ordinal))
{
_serializer.ReferenceResolver.AddObjectReference(reader.Value.ToString(), newObject);
}
else
{
if (reader.TokenType != JsonToken.Null)
SetRequiredMapping(memberName, requiredMappings);
SetObjectMember(reader, newObject, objectType, memberName);
}
if (reader.TokenType != JsonToken.Null)
SetRequiredMapping(memberName, requiredMappings);
SetObjectMember(reader, newObject, objectType, memberName);
break;
case JsonToken.EndObject:
foreach (KeyValuePair<string, bool> requiredMapping in requiredMappings)
@@ -144,13 +144,13 @@ namespace Newtonsoft.Json.Serialization
if (!isReference.Value)
return false;
return _serializer.ReferenceResolver.HasObjectReference(value);
return _serializer.ReferenceResolver.IsReferenced(value);
}
private void WriteMemberInfoProperty(JsonWriter writer, object value, JsonMemberMapping memberMapping)
{
MemberInfo member = memberMapping.Member;
string propertyName = memberMapping.MappingName;
string propertyName = memberMapping.PropertyName;
JsonConverter memberConverter = memberMapping.MemberConverter;
object defaultValue = memberMapping.DefaultValue;
@@ -203,7 +203,7 @@ namespace Newtonsoft.Json.Serialization
{
writer.WriteStartObject();
writer.WritePropertyName(JsonTypeReflector.RefPropertyName);
writer.WriteValue(_serializer.ReferenceResolver.ResolveReference(value));
writer.WriteValue(_serializer.ReferenceResolver.GetReference(value));
writer.WriteEndObject();
}
@@ -240,7 +240,11 @@ namespace Newtonsoft.Json.Serialization
if (isReference)
{
writer.WritePropertyName(JsonTypeReflector.IdPropertyName);
writer.WriteValue(_serializer.ReferenceResolver.ResolveReference(value));
writer.WriteValue(_serializer.ReferenceResolver.GetReference(value));
}
if (HasFlag(_serializer.TypeNameHandling, TypeNameHandling.Objects))
{
WriteTypeProperty(writer, objectType);
}
JsonMemberMappingCollection memberMappings = _serializer.GetMemberMappings(objectType);
@@ -255,11 +259,22 @@ namespace Newtonsoft.Json.Serialization
SerializeStack.RemoveAt(SerializeStack.Count - 1);
}
private void WriteTypeProperty(JsonWriter writer, Type type)
{
writer.WritePropertyName(JsonTypeReflector.TypePropertyName);
writer.WriteValue(type.AssemblyQualifiedName);
}
private bool HasFlag(PreserveReferencesHandling value, PreserveReferencesHandling flag)
{
return ((value & flag) == flag);
}
private bool HasFlag(TypeNameHandling value, TypeNameHandling flag)
{
return ((value & flag) == flag);
}
private bool? IsReference(Type t)
{
JsonContainerAttribute containerAttribute = JsonTypeReflector.GetJsonContainerAttribute(t);
@@ -298,13 +313,22 @@ namespace Newtonsoft.Json.Serialization
SerializeStack.Add(values);
bool isReference = IsReference(values.GetType()) ?? HasFlag(_serializer.PreserveReferencesHandling, PreserveReferencesHandling.Arrays);
if (isReference)
bool includeTypeDetails = HasFlag(_serializer.TypeNameHandling, TypeNameHandling.Arrays);
if (isReference || includeTypeDetails)
{
writer.WriteStartObject();
writer.WritePropertyName(JsonTypeReflector.IdPropertyName);
writer.WriteValue(_serializer.ReferenceResolver.ResolveReference(values));
writer.WritePropertyName("value");
if (isReference)
{
writer.WritePropertyName(JsonTypeReflector.IdPropertyName);
writer.WriteValue(_serializer.ReferenceResolver.GetReference(values));
}
if (includeTypeDetails)
{
WriteTypeProperty(writer, values.GetType());
}
writer.WritePropertyName(JsonTypeReflector.ArrayValuesPropertyName);
}
writer.WriteStartArray();
@@ -345,7 +369,11 @@ namespace Newtonsoft.Json.Serialization
if (isReference)
{
writer.WritePropertyName(JsonTypeReflector.IdPropertyName);
writer.WriteValue(_serializer.ReferenceResolver.ResolveReference(values));
writer.WriteValue(_serializer.ReferenceResolver.GetReference(values));
}
if (HasFlag(_serializer.TypeNameHandling, TypeNameHandling.Objects))
{
WriteTypeProperty(writer, values.GetType());
}
foreach (DictionaryEntry entry in values)
@@ -40,6 +40,8 @@ namespace Newtonsoft.Json.Serialization
{
public const string IdPropertyName = "$id";
public const string RefPropertyName = "$ref";
public const string TypePropertyName = "$type";
public const string ArrayValuesPropertyName = "$values";
private static readonly Dictionary<ICustomAttributeProvider, Type> ConverterTypeCache = new Dictionary<ICustomAttributeProvider, Type>();
private static readonly Dictionary<Type, Type> AssociatedMetadataTypesCache = new Dictionary<Type, Type>();
@@ -0,0 +1,21 @@
#if SILVERLIGHT || PocketPC
using System;
using System.Reflection;
namespace Newtonsoft.Json
{
/// <summary>
/// Allows users to control class loading and mandate what class to load.
/// </summary>
public abstract class SerializationBinder
{
/// <summary>
/// When overridden in a derived class, controls the binding of a serialized object to a type.
/// </summary>
/// <param name="assemblyName">Specifies the <see cref="Assembly"/> name of the serialized object.</param>
/// <param name="typeName">Specifies the <see cref="Type"/> name of the serialized object</param>
/// <returns></returns>
public abstract Type BindToType(string assemblyName, string typeName);
}
}
#endif
+31
View File
@@ -0,0 +1,31 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace Newtonsoft.Json
{
/// <summary>
/// Specifies type name handling options for the <see cref="JsonSerializer"/>.
/// </summary>
[Flags]
public enum TypeNameHandling
{
/// <summary>
/// Do not include the .NET type name when serializing types.
/// </summary>
None = 0,
/// <summary>
/// Include the .NET type name when serializing into a JSON object structure.
/// </summary>
Objects = 1,
/// <summary>
/// Include the .NET type name when serializing into a JSON array structure.
/// </summary>
Arrays = 2,
/// <summary>
/// Always include the .NET type name when serializing.
/// </summary>
All = Objects | Arrays
}
}
+4 -4
View File
@@ -72,7 +72,7 @@ namespace Newtonsoft.Json.Utilities
Type underlyingType = Enum.GetUnderlyingType(value.GetType());
ulong num = Convert.ToUInt64(value);
ulong num = Convert.ToUInt64(value, CultureInfo.InvariantCulture);
EnumValues<ulong> enumNameValues = GetNamesAndValues<T>();
IList<T> selectedFlagsValues = new List<T>();
@@ -134,8 +134,8 @@ namespace Newtonsoft.Json.Utilities
catch (OverflowException e)
{
throw new Exception(
string.Format("Value from enum with the underlying type of {0} cannot be added to dictionary with a value type of {1}. Value was too large: {2}",
Enum.GetUnderlyingType(enumType), typeof(TUnderlyingType), Convert.ToUInt64(enumValues[i])), e);
string.Format(CultureInfo.InvariantCulture, "Value from enum with the underlying type of {0} cannot be added to dictionary with a value type of {1}. Value was too large: {2}",
Enum.GetUnderlyingType(enumType), typeof(TUnderlyingType), Convert.ToUInt64(enumValues[i], CultureInfo.InvariantCulture)), e);
}
}
@@ -206,7 +206,7 @@ namespace Newtonsoft.Json.Utilities
Type enumUnderlyingType = Enum.GetUnderlyingType(enumType);
if (!typeof(TEnumType).IsAssignableFrom(enumUnderlyingType))
throw new ArgumentException(string.Format("TEnumType is not assignable from the enum's underlying type of {0}.", enumUnderlyingType.Name));
throw new ArgumentException(string.Format(CultureInfo.InvariantCulture, "TEnumType is not assignable from the enum's underlying type of {0}.", enumUnderlyingType.Name));
ulong maximumValue = 0;
IList<object> enumValues = GetValues(enumType);