In most cases this is the desired result but in certain scenarios writing the second item in the list as a reference to the first is a better solution.
- If the above JSON was deserialized now then returned list would contain two
- completely seperate Person objects with the same values. Writing references by value will also cause problems on objects where a
+ If the above JSON was deserialized now then the returned list would contain two
+ completely separate Person objects with the same values. Writing references by value will also cause problems on objects where a
circular reference occurs.
PreserveReferencesHandling
@@ -93,14 +93,18 @@
-
Now only one Person object is created and the deserialized list contains two references to it, mirroring what serialized.
+
The first Person in the list is serizlied with the addition of an object Id. The
+ second Person in JSON is now only a reference to the first.
+
With PreserveReferencesHandling on now only one Person object is created on
+ deserialization and the list contains two references to it, mirroring what we
+ started with.
IsReference on JsonObjectAttribute, JsonArrayAttribute and JsonPropertyAttribute
The PreserveReferencesHandling setting on the JsonSerializer will change
how all objects are serialized and deserialized. For fine grain control over which
- objects and members should be serialized there is the IsReference property on
+ objects and members should be serialized as a reference there is the IsReference property on
the JsonObjectAttribute, JsonArrayAttribute and JsonPropertyAttribute.
Setting IsReference on JsonObjectAttribute or JsonArrayAttribute to true will
mean the JsonSerializer will always serialize the type the attribute is against
diff --git a/Src/Doc/SerializationAttributes.html b/Src/Doc/SerializationAttributes.html
new file mode 100644
index 00000000..5c61ad71
--- /dev/null
+++ b/Src/Doc/SerializationAttributes.html
@@ -0,0 +1,118 @@
+
+
+
+ Json.NET - Quick Starts & API Documentation
+ Customizing JSON serialization with attributes
+
+
+
+
+
Attributes can be used to control how Json.NET serializes and deserializes .NET objects.
+
+
JsonObjectAttribute - Placed on classes to control how it should be serialized as a JSON object.
+
JsonArrayAttribute - Placed on collections to control how it should be serialized as a JSON array.
+
JsonPropertyAttribute - Placed on fields and properties to control how it should be serialized as a property in a JSON object.
+
JsonConverterAttribute - Placed on either classes or fields and properties to specify which JsonConverter should be used during serialization.
+
+
As well as using the built-in Json.NET attributes, Json.NET also looks for the
+ DataContract and
+ DataMember attributes when determining how JSON is to be serialized and deserialized. If both are present the Json.NET serialization attributes take precedence.
The MemberSerialization flag on this attribute specifies whether member serialization is opt-in (a member must have the JsonProperty or DataMember attribute to be serialized) or opt-out (everything is serialized by default but can be ignored with the JsonIgnoreAttribute,
+ Json.NET's default behavor).
+
Json.NET serializes .NET classes that implement IEnumerable as an
+ JSON array populated with the IEnumerable values. Placing the JsonPropertyAttribute overrides this
+ behavor and forces the serializer to serialize the class's fields and properties.
+
JsonPropertyAttribute
+
Allows the name of the serialized member to be customized. The attribute also indicates that a member should be serialized when member serialization is set to opt-in.
+
JsonIgnoreAttribute
+
Excludes a field or property from serialization.
+
JsonConverterAttribute
+
The JsonConverterAttribute specifies which JsonSerializer is used to convert an object.
+
The attribute can be placed on a class or a member. When placed on a class the JsonConverter
+ specified by the attribute will be the default way of serializing that class. When the attribute is on a field
+or property then the specified JsonConverter will always be used to serialize that value.
+
The priority of which JsonConverter is used is member attribute then class attribute and
+finally any converters passed to the JsonSerializer.
+
+
+
+
publicclassMemberConverterClass
+
{
+
publicDateTime DefaultConverter { get; set; }
+
[JsonConverter(typeof(IsoDateTimeConverter))]
+
publicDateTime MemberConverter { get; set; }
+
}
+
+
+
This example shows the JsonConverterAttribute being applied to a property.
+
+
+
+
+
DateTime date = Convert.ToDateTime("1970-01-01T00:00:00Z").ToUniversalTime();
+
+
+
+
\ No newline at end of file
diff --git a/Src/Doc/SerializingJSON.html b/Src/Doc/SerializingJSON.html
index 5b385969..807eaf52 100644
--- a/Src/Doc/SerializingJSON.html
+++ b/Src/Doc/SerializingJSON.html
@@ -98,87 +98,7 @@ the member's DefaultValueAttribute. Include or ignore.
TypeNameHandling
Controls how .NET type names are used when serializing and deserializing JSON. If
type names are SDFSDFSDF
-
Serialization Attributes
-
There are a number of attributes that can be placed on a class to control how it is serialized.
-
Note that as well as using the built-in Json.NET attributes, Json.NET also looks for the
- DataContract and
- DataMember attributes when determining how JSON is to be serialized and deserialized. If both are present the Json.NET serialization attributes take precedence.
The MemberSerialization flag on this attribute specifies whether member serialization is opt-in (a member must have the JsonProperty or DataMember attribute to be serialized) or opt-out (everything is serialized by default but can be ignored with the JsonIgnoreAttribute).
-
.NET classes that implement IEnumerable are automatically serialized as an array, populated with the IEnumerable values. Placing the JsonPropertyAttribute will override this and force the serializer to serialize the class's fields and properties.
-
JsonPropertyAttribute
-
Allows the name of the serialized member to be customized. The attribute also indicates that a member should be serialized when member serialization is set to opt-in.
-
JsonIgnoreAttribute
-
Excludes a field or property from serialization.
-
JsonConverterAttribute
-
The JsonConverterAttribute specifies which JsonSerializer is used to convert an object.
-
The attribute can be placed on a class or a member. When placed on a class the JsonConverter
- specified by the attribute will be the default way of serializing that class. When the attribute is on a field
-or property then the specified JsonConverter will always be used to serialize that value.
-
The priority of which JsonConverter is used is member attribute then class attribute and
-finally any converters passed to the JsonSerializer.
-
-
-
-
publicclassMemberConverterClass
-
{
-
publicDateTime DefaultConverter { get; set; }
-
[JsonConverter(typeof(IsoDateTimeConverter))]
-
publicDateTime MemberConverter { get; set; }
-
}
-
-
-
This example shows the JsonConverterAttribute being applied to a property.
-
-
-
-
-
DateTime date = Convert.ToDateTime("1970-01-01T00:00:00Z").ToUniversalTime();
JsonConverters allows JSON to be manually written during serialization and read during deserialization. This is useful for particularly complex JSON structures or for when you want to change how a type is serialized.
diff --git a/Src/Doc/doc.shfb b/Src/Doc/doc.shfb
index e3bc42a9..d6ba72b3 100644
--- a/Src/Doc/doc.shfb
+++ b/Src/Doc/doc.shfb
@@ -23,6 +23,7 @@
+ Summary, Parameter, Returns, AutoDocumentCtors, Namespace, TypeParameter
diff --git a/Src/Doc/doc.sitemap b/Src/Doc/doc.sitemap
index 3902d0bb..e0c17bfb 100644
--- a/Src/Doc/doc.sitemap
+++ b/Src/Doc/doc.sitemap
@@ -2,9 +2,10 @@
+
-
+
diff --git a/Src/Newtonsoft.Json.Tests/EntityDataModel.Designer.cs b/Src/Newtonsoft.Json.Tests/EntityDataModel.Designer.cs
deleted file mode 100644
index 954fa14a..00000000
--- a/Src/Newtonsoft.Json.Tests/EntityDataModel.Designer.cs
+++ /dev/null
@@ -1,242 +0,0 @@
-//------------------------------------------------------------------------------
-//
-// This code was generated by a tool.
-// Runtime Version:2.0.50727.3053
-//
-// Changes to this file may cause incorrect behavior and will be lost if
-// the code is regenerated.
-//
-//------------------------------------------------------------------------------
-
-[assembly: global::System.Data.Objects.DataClasses.EdmSchemaAttribute()]
-[assembly: global::System.Data.Objects.DataClasses.EdmRelationshipAttribute("EntityDataModel", "PurchasePurchaseLine", "Purchase", global::System.Data.Metadata.Edm.RelationshipMultiplicity.One, typeof(Newtonsoft.Json.Tests.Purchase), "PurchaseLine", global::System.Data.Metadata.Edm.RelationshipMultiplicity.Many, typeof(Newtonsoft.Json.Tests.PurchaseLine))]
-
-// Original file name:
-// Generation date: 7/09/2008 7:58:08 p.m.
-namespace Newtonsoft.Json.Tests
-{
-
- ///
- /// There are no comments for EntityDataModelContainer in the schema.
- ///
- public partial class EntityDataModelContainer : global::System.Data.Objects.ObjectContext
- {
- ///
- /// Initializes a new EntityDataModelContainer object using the connection string found in the 'EntityDataModelContainer' section of the application configuration file.
- ///
- public EntityDataModelContainer() :
- base("name=EntityDataModelContainer", "EntityDataModelContainer")
- {
- this.OnContextCreated();
- }
- ///
- /// Initialize a new EntityDataModelContainer object.
- ///
- public EntityDataModelContainer(string connectionString) :
- base(connectionString, "EntityDataModelContainer")
- {
- this.OnContextCreated();
- }
- ///
- /// Initialize a new EntityDataModelContainer object.
- ///
- public EntityDataModelContainer(global::System.Data.EntityClient.EntityConnection connection) :
- base(connection, "EntityDataModelContainer")
- {
- this.OnContextCreated();
- }
- partial void OnContextCreated();
- ///
- /// There are no comments for PurchaseSet in the schema.
- ///
- public global::System.Data.Objects.ObjectQuery PurchaseSet
- {
- get
- {
- if ((this._PurchaseSet == null))
- {
- this._PurchaseSet = base.CreateQuery("[PurchaseSet]");
- }
- return this._PurchaseSet;
- }
- }
- private global::System.Data.Objects.ObjectQuery _PurchaseSet;
- ///
- /// There are no comments for PurchaseLineSet in the schema.
- ///
- public global::System.Data.Objects.ObjectQuery PurchaseLineSet
- {
- get
- {
- if ((this._PurchaseLineSet == null))
- {
- this._PurchaseLineSet = base.CreateQuery("[PurchaseLineSet]");
- }
- return this._PurchaseLineSet;
- }
- }
- private global::System.Data.Objects.ObjectQuery _PurchaseLineSet;
- ///
- /// There are no comments for PurchaseSet in the schema.
- ///
- public void AddToPurchaseSet(Purchase purchase)
- {
- base.AddObject("PurchaseSet", purchase);
- }
- ///
- /// There are no comments for PurchaseLineSet in the schema.
- ///
- public void AddToPurchaseLineSet(PurchaseLine purchaseLine)
- {
- base.AddObject("PurchaseLineSet", purchaseLine);
- }
- }
- ///
- /// There are no comments for EntityDataModel.Purchase in the schema.
- ///
- ///
- /// Id
- ///
- [global::System.Data.Objects.DataClasses.EdmEntityTypeAttribute(NamespaceName="EntityDataModel", Name="Purchase")]
- [global::System.Runtime.Serialization.DataContractAttribute(IsReference=true)]
- [global::System.Serializable()]
- public partial class Purchase : global::System.Data.Objects.DataClasses.EntityObject
- {
- ///
- /// Create a new Purchase object.
- ///
- /// Initial value of Id.
- public static Purchase CreatePurchase(int id)
- {
- Purchase purchase = new Purchase();
- purchase.Id = id;
- return purchase;
- }
- ///
- /// There are no comments for Property Id in the schema.
- ///
- [global::System.Data.Objects.DataClasses.EdmScalarPropertyAttribute(EntityKeyProperty=true, IsNullable=false)]
- [global::System.Runtime.Serialization.DataMemberAttribute()]
- public int Id
- {
- get
- {
- return this._Id;
- }
- set
- {
- this.OnIdChanging(value);
- this.ReportPropertyChanging("Id");
- this._Id = global::System.Data.Objects.DataClasses.StructuralObject.SetValidValue(value);
- this.ReportPropertyChanged("Id");
- this.OnIdChanged();
- }
- }
- private int _Id;
- partial void OnIdChanging(int value);
- partial void OnIdChanged();
- ///
- /// There are no comments for PurchaseLine in the schema.
- ///
- [global::System.Data.Objects.DataClasses.EdmRelationshipNavigationPropertyAttribute("EntityDataModel", "PurchasePurchaseLine", "PurchaseLine")]
- [global::System.Xml.Serialization.XmlIgnoreAttribute()]
- [global::System.Xml.Serialization.SoapIgnoreAttribute()]
- [global::System.Runtime.Serialization.DataMemberAttribute()]
- public global::System.Data.Objects.DataClasses.EntityCollection PurchaseLine
- {
- get
- {
- return ((global::System.Data.Objects.DataClasses.IEntityWithRelationships)(this)).RelationshipManager.GetRelatedCollection("EntityDataModel.PurchasePurchaseLine", "PurchaseLine");
- }
- set
- {
- if ((value != null))
- {
- ((global::System.Data.Objects.DataClasses.IEntityWithRelationships)(this)).RelationshipManager.InitializeRelatedCollection("EntityDataModel.PurchasePurchaseLine", "PurchaseLine", value);
- }
- }
- }
- }
- ///
- /// There are no comments for EntityDataModel.PurchaseLine in the schema.
- ///
- ///
- /// Id
- ///
- [global::System.Data.Objects.DataClasses.EdmEntityTypeAttribute(NamespaceName="EntityDataModel", Name="PurchaseLine")]
- [global::System.Runtime.Serialization.DataContractAttribute(IsReference=true)]
- [global::System.Serializable()]
- public partial class PurchaseLine : global::System.Data.Objects.DataClasses.EntityObject
- {
- ///
- /// Create a new PurchaseLine object.
- ///
- /// Initial value of Id.
- public static PurchaseLine CreatePurchaseLine(int id)
- {
- PurchaseLine purchaseLine = new PurchaseLine();
- purchaseLine.Id = id;
- return purchaseLine;
- }
- ///
- /// There are no comments for Property Id in the schema.
- ///
- [global::System.Data.Objects.DataClasses.EdmScalarPropertyAttribute(EntityKeyProperty=true, IsNullable=false)]
- [global::System.Runtime.Serialization.DataMemberAttribute()]
- public int Id
- {
- get
- {
- return this._Id;
- }
- set
- {
- this.OnIdChanging(value);
- this.ReportPropertyChanging("Id");
- this._Id = global::System.Data.Objects.DataClasses.StructuralObject.SetValidValue(value);
- this.ReportPropertyChanged("Id");
- this.OnIdChanged();
- }
- }
- private int _Id;
- partial void OnIdChanging(int value);
- partial void OnIdChanged();
- ///
- /// There are no comments for Purchase in the schema.
- ///
- [global::System.Data.Objects.DataClasses.EdmRelationshipNavigationPropertyAttribute("EntityDataModel", "PurchasePurchaseLine", "Purchase")]
- [global::System.Xml.Serialization.XmlIgnoreAttribute()]
- [global::System.Xml.Serialization.SoapIgnoreAttribute()]
- [global::System.Runtime.Serialization.DataMemberAttribute()]
- public Purchase Purchase
- {
- get
- {
- return ((global::System.Data.Objects.DataClasses.IEntityWithRelationships)(this)).RelationshipManager.GetRelatedReference("EntityDataModel.PurchasePurchaseLine", "Purchase").Value;
- }
- set
- {
- ((global::System.Data.Objects.DataClasses.IEntityWithRelationships)(this)).RelationshipManager.GetRelatedReference("EntityDataModel.PurchasePurchaseLine", "Purchase").Value = value;
- }
- }
- ///
- /// There are no comments for Purchase in the schema.
- ///
- [global::System.ComponentModel.BrowsableAttribute(false)]
- [global::System.Runtime.Serialization.DataMemberAttribute()]
- public global::System.Data.Objects.DataClasses.EntityReference PurchaseReference
- {
- get
- {
- return ((global::System.Data.Objects.DataClasses.IEntityWithRelationships)(this)).RelationshipManager.GetRelatedReference("EntityDataModel.PurchasePurchaseLine", "Purchase");
- }
- set
- {
- if ((value != null))
- {
- ((global::System.Data.Objects.DataClasses.IEntityWithRelationships)(this)).RelationshipManager.InitializeRelatedReference("EntityDataModel.PurchasePurchaseLine", "Purchase", value);
- }
- }
- }
- }
-}
diff --git a/Src/Newtonsoft.Json.Tests/EntityDataModel.edmx b/Src/Newtonsoft.Json.Tests/EntityDataModel.edmx
deleted file mode 100644
index aec3aa44..00000000
--- a/Src/Newtonsoft.Json.Tests/EntityDataModel.edmx
+++ /dev/null
@@ -1,67 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/Src/Newtonsoft.Json.Tests/ExceptionTests.cs b/Src/Newtonsoft.Json.Tests/ExceptionTests.cs
new file mode 100644
index 00000000..cfa560fd
--- /dev/null
+++ b/Src/Newtonsoft.Json.Tests/ExceptionTests.cs
@@ -0,0 +1,72 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using Newtonsoft.Json.Schema;
+using NUnit.Framework;
+
+namespace Newtonsoft.Json.Tests
+{
+ public class ExceptionTests : TestFixtureBase
+ {
+ [Test]
+ public void JsonSerializationException()
+ {
+ JsonSerializationException exception = new JsonSerializationException();
+ Assert.AreEqual("Exception of type 'Newtonsoft.Json.JsonSerializationException' was thrown.", exception.Message);
+
+ exception = new JsonSerializationException("Message!");
+ Assert.AreEqual("Message!", exception.Message);
+ Assert.AreEqual(null, exception.InnerException);
+
+ exception = new JsonSerializationException("Message!", new Exception("Inner!"));
+ Assert.AreEqual("Message!", exception.Message);
+ Assert.AreEqual("Inner!", exception.InnerException.Message);
+ }
+
+ [Test]
+ public void JsonWriterException()
+ {
+ JsonWriterException exception = new JsonWriterException();
+ Assert.AreEqual("Exception of type 'Newtonsoft.Json.JsonWriterException' was thrown.", exception.Message);
+
+ exception = new JsonWriterException("Message!");
+ Assert.AreEqual("Message!", exception.Message);
+ Assert.AreEqual(null, exception.InnerException);
+
+ exception = new JsonWriterException("Message!", new Exception("Inner!"));
+ Assert.AreEqual("Message!", exception.Message);
+ Assert.AreEqual("Inner!", exception.InnerException.Message);
+ }
+
+ [Test]
+ public void JsonReaderException()
+ {
+ JsonReaderException exception = new JsonReaderException();
+ Assert.AreEqual("Exception of type 'Newtonsoft.Json.JsonReaderException' was thrown.", exception.Message);
+
+ exception = new JsonReaderException("Message!");
+ Assert.AreEqual("Message!", exception.Message);
+ Assert.AreEqual(null, exception.InnerException);
+
+ exception = new JsonReaderException("Message!", new Exception("Inner!"));
+ Assert.AreEqual("Message!", exception.Message);
+ Assert.AreEqual("Inner!", exception.InnerException.Message);
+ }
+
+ [Test]
+ public void JsonSchemaException()
+ {
+ JsonSchemaException exception = new JsonSchemaException();
+ Assert.AreEqual("Exception of type 'Newtonsoft.Json.Schema.JsonSchemaException' was thrown.", exception.Message);
+
+ exception = new JsonSchemaException("Message!");
+ Assert.AreEqual("Message!", exception.Message);
+ Assert.AreEqual(null, exception.InnerException);
+
+ exception = new JsonSchemaException("Message!", new Exception("Inner!"));
+ Assert.AreEqual("Message!", exception.Message);
+ Assert.AreEqual("Inner!", exception.InnerException.Message);
+ }
+ }
+}
\ No newline at end of file
diff --git a/Src/Newtonsoft.Json.Tests/FileSystemEntityModel.Designer.cs b/Src/Newtonsoft.Json.Tests/FileSystemEntityModel.Designer.cs
new file mode 100644
index 00000000..cc3a68ab
--- /dev/null
+++ b/Src/Newtonsoft.Json.Tests/FileSystemEntityModel.Designer.cs
@@ -0,0 +1,449 @@
+//------------------------------------------------------------------------------
+//
+// This code was generated by a tool.
+// Runtime Version:2.0.50727.3074
+//
+// Changes to this file may cause incorrect behavior and will be lost if
+// the code is regenerated.
+//
+//------------------------------------------------------------------------------
+
+[assembly: global::System.Data.Objects.DataClasses.EdmSchemaAttribute()]
+[assembly: global::System.Data.Objects.DataClasses.EdmRelationshipAttribute("DataServicesTestDatabaseModel", "FK_File_Folder", "Folder", global::System.Data.Metadata.Edm.RelationshipMultiplicity.One, typeof(Newtonsoft.Json.Tests.Folder), "File", global::System.Data.Metadata.Edm.RelationshipMultiplicity.Many, typeof(Newtonsoft.Json.Tests.File))]
+[assembly: global::System.Data.Objects.DataClasses.EdmRelationshipAttribute("DataServicesTestDatabaseModel", "FK_Folder_Folder", "Folder", global::System.Data.Metadata.Edm.RelationshipMultiplicity.ZeroOrOne, typeof(Newtonsoft.Json.Tests.Folder), "Folder1", global::System.Data.Metadata.Edm.RelationshipMultiplicity.Many, typeof(Newtonsoft.Json.Tests.Folder))]
+
+// Original file name:
+// Generation date: 26/07/2009 4:51:53 p.m.
+namespace Newtonsoft.Json.Tests
+{
+
+ ///
+ /// There are no comments for DataServicesTestDatabaseEntities in the schema.
+ ///
+ public partial class DataServicesTestDatabaseEntities : global::System.Data.Objects.ObjectContext
+ {
+ ///
+ /// Initializes a new DataServicesTestDatabaseEntities object using the connection string found in the 'DataServicesTestDatabaseEntities' section of the application configuration file.
+ ///
+ public DataServicesTestDatabaseEntities() :
+ base("name=DataServicesTestDatabaseEntities", "DataServicesTestDatabaseEntities")
+ {
+ this.OnContextCreated();
+ }
+ ///
+ /// Initialize a new DataServicesTestDatabaseEntities object.
+ ///
+ public DataServicesTestDatabaseEntities(string connectionString) :
+ base(connectionString, "DataServicesTestDatabaseEntities")
+ {
+ this.OnContextCreated();
+ }
+ ///
+ /// Initialize a new DataServicesTestDatabaseEntities object.
+ ///
+ public DataServicesTestDatabaseEntities(global::System.Data.EntityClient.EntityConnection connection) :
+ base(connection, "DataServicesTestDatabaseEntities")
+ {
+ this.OnContextCreated();
+ }
+ partial void OnContextCreated();
+ ///
+ /// There are no comments for File in the schema.
+ ///
+ public global::System.Data.Objects.ObjectQuery File
+ {
+ get
+ {
+ if ((this._File == null))
+ {
+ this._File = base.CreateQuery("[File]");
+ }
+ return this._File;
+ }
+ }
+ private global::System.Data.Objects.ObjectQuery _File;
+ ///
+ /// There are no comments for Folder in the schema.
+ ///
+ public global::System.Data.Objects.ObjectQuery Folder
+ {
+ get
+ {
+ if ((this._Folder == null))
+ {
+ this._Folder = base.CreateQuery("[Folder]");
+ }
+ return this._Folder;
+ }
+ }
+ private global::System.Data.Objects.ObjectQuery _Folder;
+ ///
+ /// There are no comments for File in the schema.
+ ///
+ public void AddToFile(File file)
+ {
+ base.AddObject("File", file);
+ }
+ ///
+ /// There are no comments for Folder in the schema.
+ ///
+ public void AddToFolder(Folder folder)
+ {
+ base.AddObject("Folder", folder);
+ }
+ }
+ ///
+ /// There are no comments for DataServicesTestDatabaseModel.File in the schema.
+ ///
+ ///
+ /// FileId
+ ///
+ [global::System.Data.Objects.DataClasses.EdmEntityTypeAttribute(NamespaceName="DataServicesTestDatabaseModel", Name="File")]
+ [global::System.Runtime.Serialization.DataContractAttribute(IsReference=true)]
+ [global::System.Serializable()]
+ public partial class File : global::System.Data.Objects.DataClasses.EntityObject
+ {
+ ///
+ /// Create a new File object.
+ ///
+ /// Initial value of FileId.
+ /// Initial value of Name.
+ /// Initial value of Description.
+ /// Initial value of CreatedDate.
+ public static File CreateFile(global::System.Guid fileId, string name, string description, global::System.DateTime createdDate)
+ {
+ File file = new File();
+ file.FileId = fileId;
+ file.Name = name;
+ file.Description = description;
+ file.CreatedDate = createdDate;
+ return file;
+ }
+ ///
+ /// There are no comments for Property FileId in the schema.
+ ///
+ [global::System.Data.Objects.DataClasses.EdmScalarPropertyAttribute(EntityKeyProperty=true, IsNullable=false)]
+ [global::System.Runtime.Serialization.DataMemberAttribute()]
+ public global::System.Guid FileId
+ {
+ get
+ {
+ return this._FileId;
+ }
+ set
+ {
+ this.OnFileIdChanging(value);
+ this.ReportPropertyChanging("FileId");
+ this._FileId = global::System.Data.Objects.DataClasses.StructuralObject.SetValidValue(value);
+ this.ReportPropertyChanged("FileId");
+ this.OnFileIdChanged();
+ }
+ }
+ private global::System.Guid _FileId;
+ partial void OnFileIdChanging(global::System.Guid value);
+ partial void OnFileIdChanged();
+ ///
+ /// There are no comments for Property Name in the schema.
+ ///
+ [global::System.Data.Objects.DataClasses.EdmScalarPropertyAttribute(IsNullable=false)]
+ [global::System.Runtime.Serialization.DataMemberAttribute()]
+ public string Name
+ {
+ get
+ {
+ return this._Name;
+ }
+ set
+ {
+ this.OnNameChanging(value);
+ this.ReportPropertyChanging("Name");
+ this._Name = global::System.Data.Objects.DataClasses.StructuralObject.SetValidValue(value, false);
+ this.ReportPropertyChanged("Name");
+ this.OnNameChanged();
+ }
+ }
+ private string _Name;
+ partial void OnNameChanging(string value);
+ partial void OnNameChanged();
+ ///
+ /// There are no comments for Property Description in the schema.
+ ///
+ [global::System.Data.Objects.DataClasses.EdmScalarPropertyAttribute(IsNullable=false)]
+ [global::System.Runtime.Serialization.DataMemberAttribute()]
+ public string Description
+ {
+ get
+ {
+ return this._Description;
+ }
+ set
+ {
+ this.OnDescriptionChanging(value);
+ this.ReportPropertyChanging("Description");
+ this._Description = global::System.Data.Objects.DataClasses.StructuralObject.SetValidValue(value, false);
+ this.ReportPropertyChanged("Description");
+ this.OnDescriptionChanged();
+ }
+ }
+ private string _Description;
+ partial void OnDescriptionChanging(string value);
+ partial void OnDescriptionChanged();
+ ///
+ /// There are no comments for Property CreatedDate in the schema.
+ ///
+ [global::System.Data.Objects.DataClasses.EdmScalarPropertyAttribute(IsNullable=false)]
+ [global::System.Runtime.Serialization.DataMemberAttribute()]
+ public global::System.DateTime CreatedDate
+ {
+ get
+ {
+ return this._CreatedDate;
+ }
+ set
+ {
+ this.OnCreatedDateChanging(value);
+ this.ReportPropertyChanging("CreatedDate");
+ this._CreatedDate = global::System.Data.Objects.DataClasses.StructuralObject.SetValidValue(value);
+ this.ReportPropertyChanged("CreatedDate");
+ this.OnCreatedDateChanged();
+ }
+ }
+ private global::System.DateTime _CreatedDate;
+ partial void OnCreatedDateChanging(global::System.DateTime value);
+ partial void OnCreatedDateChanged();
+ ///
+ /// There are no comments for Folder in the schema.
+ ///
+ [global::System.Data.Objects.DataClasses.EdmRelationshipNavigationPropertyAttribute("DataServicesTestDatabaseModel", "FK_File_Folder", "Folder")]
+ [global::System.Xml.Serialization.XmlIgnoreAttribute()]
+ [global::System.Xml.Serialization.SoapIgnoreAttribute()]
+ [global::System.Runtime.Serialization.DataMemberAttribute()]
+ public Folder Folder
+ {
+ get
+ {
+ return ((global::System.Data.Objects.DataClasses.IEntityWithRelationships)(this)).RelationshipManager.GetRelatedReference("DataServicesTestDatabaseModel.FK_File_Folder", "Folder").Value;
+ }
+ set
+ {
+ ((global::System.Data.Objects.DataClasses.IEntityWithRelationships)(this)).RelationshipManager.GetRelatedReference("DataServicesTestDatabaseModel.FK_File_Folder", "Folder").Value = value;
+ }
+ }
+ ///
+ /// There are no comments for Folder in the schema.
+ ///
+ [global::System.ComponentModel.BrowsableAttribute(false)]
+ [global::System.Runtime.Serialization.DataMemberAttribute()]
+ public global::System.Data.Objects.DataClasses.EntityReference FolderReference
+ {
+ get
+ {
+ return ((global::System.Data.Objects.DataClasses.IEntityWithRelationships)(this)).RelationshipManager.GetRelatedReference("DataServicesTestDatabaseModel.FK_File_Folder", "Folder");
+ }
+ set
+ {
+ if ((value != null))
+ {
+ ((global::System.Data.Objects.DataClasses.IEntityWithRelationships)(this)).RelationshipManager.InitializeRelatedReference("DataServicesTestDatabaseModel.FK_File_Folder", "Folder", value);
+ }
+ }
+ }
+ }
+ ///
+ /// There are no comments for DataServicesTestDatabaseModel.Folder in the schema.
+ ///
+ ///
+ /// FolderId
+ ///
+ [global::System.Data.Objects.DataClasses.EdmEntityTypeAttribute(NamespaceName="DataServicesTestDatabaseModel", Name="Folder")]
+ [global::System.Runtime.Serialization.DataContractAttribute(IsReference=true)]
+ [global::System.Serializable()]
+ public partial class Folder : global::System.Data.Objects.DataClasses.EntityObject
+ {
+ ///
+ /// Create a new Folder object.
+ ///
+ /// Initial value of FolderId.
+ /// Initial value of Name.
+ /// Initial value of CreatedDate.
+ public static Folder CreateFolder(global::System.Guid folderId, string name, global::System.DateTime createdDate)
+ {
+ Folder folder = new Folder();
+ folder.FolderId = folderId;
+ folder.Name = name;
+ folder.CreatedDate = createdDate;
+ return folder;
+ }
+ ///
+ /// There are no comments for Property FolderId in the schema.
+ ///
+ [global::System.Data.Objects.DataClasses.EdmScalarPropertyAttribute(EntityKeyProperty=true, IsNullable=false)]
+ [global::System.Runtime.Serialization.DataMemberAttribute()]
+ public global::System.Guid FolderId
+ {
+ get
+ {
+ return this._FolderId;
+ }
+ set
+ {
+ this.OnFolderIdChanging(value);
+ this.ReportPropertyChanging("FolderId");
+ this._FolderId = global::System.Data.Objects.DataClasses.StructuralObject.SetValidValue(value);
+ this.ReportPropertyChanged("FolderId");
+ this.OnFolderIdChanged();
+ }
+ }
+ private global::System.Guid _FolderId;
+ partial void OnFolderIdChanging(global::System.Guid value);
+ partial void OnFolderIdChanged();
+ ///
+ /// There are no comments for Property Name in the schema.
+ ///
+ [global::System.Data.Objects.DataClasses.EdmScalarPropertyAttribute(IsNullable=false)]
+ [global::System.Runtime.Serialization.DataMemberAttribute()]
+ public string Name
+ {
+ get
+ {
+ return this._Name;
+ }
+ set
+ {
+ this.OnNameChanging(value);
+ this.ReportPropertyChanging("Name");
+ this._Name = global::System.Data.Objects.DataClasses.StructuralObject.SetValidValue(value, false);
+ this.ReportPropertyChanged("Name");
+ this.OnNameChanged();
+ }
+ }
+ private string _Name;
+ partial void OnNameChanging(string value);
+ partial void OnNameChanged();
+ ///
+ /// There are no comments for Property Description in the schema.
+ ///
+ [global::System.Data.Objects.DataClasses.EdmScalarPropertyAttribute()]
+ [global::System.Runtime.Serialization.DataMemberAttribute()]
+ public string Description
+ {
+ get
+ {
+ return this._Description;
+ }
+ set
+ {
+ this.OnDescriptionChanging(value);
+ this.ReportPropertyChanging("Description");
+ this._Description = global::System.Data.Objects.DataClasses.StructuralObject.SetValidValue(value, true);
+ this.ReportPropertyChanged("Description");
+ this.OnDescriptionChanged();
+ }
+ }
+ private string _Description;
+ partial void OnDescriptionChanging(string value);
+ partial void OnDescriptionChanged();
+ ///
+ /// There are no comments for Property CreatedDate in the schema.
+ ///
+ [global::System.Data.Objects.DataClasses.EdmScalarPropertyAttribute(IsNullable=false)]
+ [global::System.Runtime.Serialization.DataMemberAttribute()]
+ public global::System.DateTime CreatedDate
+ {
+ get
+ {
+ return this._CreatedDate;
+ }
+ set
+ {
+ this.OnCreatedDateChanging(value);
+ this.ReportPropertyChanging("CreatedDate");
+ this._CreatedDate = global::System.Data.Objects.DataClasses.StructuralObject.SetValidValue(value);
+ this.ReportPropertyChanged("CreatedDate");
+ this.OnCreatedDateChanged();
+ }
+ }
+ private global::System.DateTime _CreatedDate;
+ partial void OnCreatedDateChanging(global::System.DateTime value);
+ partial void OnCreatedDateChanged();
+ ///
+ /// There are no comments for Files in the schema.
+ ///
+ [global::System.Data.Objects.DataClasses.EdmRelationshipNavigationPropertyAttribute("DataServicesTestDatabaseModel", "FK_File_Folder", "File")]
+ [global::System.Xml.Serialization.XmlIgnoreAttribute()]
+ [global::System.Xml.Serialization.SoapIgnoreAttribute()]
+ [global::System.Runtime.Serialization.DataMemberAttribute()]
+ public global::System.Data.Objects.DataClasses.EntityCollection Files
+ {
+ get
+ {
+ return ((global::System.Data.Objects.DataClasses.IEntityWithRelationships)(this)).RelationshipManager.GetRelatedCollection("DataServicesTestDatabaseModel.FK_File_Folder", "File");
+ }
+ set
+ {
+ if ((value != null))
+ {
+ ((global::System.Data.Objects.DataClasses.IEntityWithRelationships)(this)).RelationshipManager.InitializeRelatedCollection("DataServicesTestDatabaseModel.FK_File_Folder", "File", value);
+ }
+ }
+ }
+ ///
+ /// There are no comments for ChildFolders in the schema.
+ ///
+ [global::System.Data.Objects.DataClasses.EdmRelationshipNavigationPropertyAttribute("DataServicesTestDatabaseModel", "FK_Folder_Folder", "Folder1")]
+ [global::System.Xml.Serialization.XmlIgnoreAttribute()]
+ [global::System.Xml.Serialization.SoapIgnoreAttribute()]
+ [global::System.Runtime.Serialization.DataMemberAttribute()]
+ public global::System.Data.Objects.DataClasses.EntityCollection ChildFolders
+ {
+ get
+ {
+ return ((global::System.Data.Objects.DataClasses.IEntityWithRelationships)(this)).RelationshipManager.GetRelatedCollection("DataServicesTestDatabaseModel.FK_Folder_Folder", "Folder1");
+ }
+ set
+ {
+ if ((value != null))
+ {
+ ((global::System.Data.Objects.DataClasses.IEntityWithRelationships)(this)).RelationshipManager.InitializeRelatedCollection("DataServicesTestDatabaseModel.FK_Folder_Folder", "Folder1", value);
+ }
+ }
+ }
+ ///
+ /// There are no comments for ParentFolder in the schema.
+ ///
+ [global::System.Data.Objects.DataClasses.EdmRelationshipNavigationPropertyAttribute("DataServicesTestDatabaseModel", "FK_Folder_Folder", "Folder")]
+ [global::System.Xml.Serialization.XmlIgnoreAttribute()]
+ [global::System.Xml.Serialization.SoapIgnoreAttribute()]
+ [global::System.Runtime.Serialization.DataMemberAttribute()]
+ public Folder ParentFolder
+ {
+ get
+ {
+ return ((global::System.Data.Objects.DataClasses.IEntityWithRelationships)(this)).RelationshipManager.GetRelatedReference("DataServicesTestDatabaseModel.FK_Folder_Folder", "Folder").Value;
+ }
+ set
+ {
+ ((global::System.Data.Objects.DataClasses.IEntityWithRelationships)(this)).RelationshipManager.GetRelatedReference("DataServicesTestDatabaseModel.FK_Folder_Folder", "Folder").Value = value;
+ }
+ }
+ ///
+ /// There are no comments for ParentFolder in the schema.
+ ///
+ [global::System.ComponentModel.BrowsableAttribute(false)]
+ [global::System.Runtime.Serialization.DataMemberAttribute()]
+ public global::System.Data.Objects.DataClasses.EntityReference ParentFolderReference
+ {
+ get
+ {
+ return ((global::System.Data.Objects.DataClasses.IEntityWithRelationships)(this)).RelationshipManager.GetRelatedReference("DataServicesTestDatabaseModel.FK_Folder_Folder", "Folder");
+ }
+ set
+ {
+ if ((value != null))
+ {
+ ((global::System.Data.Objects.DataClasses.IEntityWithRelationships)(this)).RelationshipManager.InitializeRelatedReference("DataServicesTestDatabaseModel.FK_Folder_Folder", "Folder", value);
+ }
+ }
+ }
+ }
+}
diff --git a/Src/Newtonsoft.Json.Tests/FileSystemEntityModel.edmx b/Src/Newtonsoft.Json.Tests/FileSystemEntityModel.edmx
new file mode 100644
index 00000000..e80aa796
--- /dev/null
+++ b/Src/Newtonsoft.Json.Tests/FileSystemEntityModel.edmx
@@ -0,0 +1,184 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Src/Newtonsoft.Json.Tests/JsonArrayAttributeTests.cs b/Src/Newtonsoft.Json.Tests/JsonArrayAttributeTests.cs
new file mode 100644
index 00000000..dcf8e70b
--- /dev/null
+++ b/Src/Newtonsoft.Json.Tests/JsonArrayAttributeTests.cs
@@ -0,0 +1,63 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using NUnit.Framework;
+
+namespace Newtonsoft.Json.Tests
+{
+ public class JsonArrayAttributeTests : TestFixtureBase
+ {
+ [Test]
+ public void IsReferenceTest()
+ {
+ JsonPropertyAttribute attribute = new JsonPropertyAttribute();
+ Assert.AreEqual(null, attribute._isReference);
+ Assert.AreEqual(false, attribute.IsReference);
+
+ attribute.IsReference = false;
+ Assert.AreEqual(false, attribute._isReference);
+ Assert.AreEqual(false, attribute.IsReference);
+
+ attribute.IsReference = true;
+ Assert.AreEqual(true, attribute._isReference);
+ Assert.AreEqual(true, attribute.IsReference);
+ }
+
+ [Test]
+ public void NullValueHandlingTest()
+ {
+ JsonPropertyAttribute attribute = new JsonPropertyAttribute();
+ Assert.AreEqual(null, attribute._nullValueHandling);
+ Assert.AreEqual(NullValueHandling.Include, attribute.NullValueHandling);
+
+ attribute.NullValueHandling = NullValueHandling.Ignore;
+ Assert.AreEqual(NullValueHandling.Ignore, attribute._nullValueHandling);
+ Assert.AreEqual(NullValueHandling.Ignore, attribute.NullValueHandling);
+ }
+
+ [Test]
+ public void DefaultValueHandlingTest()
+ {
+ JsonPropertyAttribute attribute = new JsonPropertyAttribute();
+ Assert.AreEqual(null, attribute._defaultValueHandling);
+ Assert.AreEqual(DefaultValueHandling.Include, attribute.DefaultValueHandling);
+
+ attribute.DefaultValueHandling = DefaultValueHandling.Ignore;
+ Assert.AreEqual(DefaultValueHandling.Ignore, attribute._defaultValueHandling);
+ Assert.AreEqual(DefaultValueHandling.Ignore, attribute.DefaultValueHandling);
+ }
+
+ [Test]
+ public void ReferenceLoopHandlingTest()
+ {
+ JsonPropertyAttribute attribute = new JsonPropertyAttribute();
+ Assert.AreEqual(null, attribute._defaultValueHandling);
+ Assert.AreEqual(ReferenceLoopHandling.Error, attribute.ReferenceLoopHandling);
+
+ attribute.ReferenceLoopHandling = ReferenceLoopHandling.Ignore;
+ Assert.AreEqual(ReferenceLoopHandling.Ignore, attribute._referenceLoopHandling);
+ Assert.AreEqual(ReferenceLoopHandling.Ignore, attribute.ReferenceLoopHandling);
+ }
+ }
+}
\ No newline at end of file
diff --git a/Src/Newtonsoft.Json.Tests/JsonSerializerTest.cs b/Src/Newtonsoft.Json.Tests/JsonSerializerTest.cs
index bd9a1560..890699c4 100644
--- a/Src/Newtonsoft.Json.Tests/JsonSerializerTest.cs
+++ b/Src/Newtonsoft.Json.Tests/JsonSerializerTest.cs
@@ -1323,7 +1323,7 @@ keyword such as type of business.""
Person person = GetPerson();
- using (FileStream fs = File.Open(@"c:\person.json", FileMode.CreateNew))
+ using (FileStream fs = System.IO.File.Open(@"c:\person.json", FileMode.CreateNew))
using (StreamWriter sw = new StreamWriter(fs))
using (JsonWriter jw = new JsonTextWriter(sw))
{
diff --git a/Src/Newtonsoft.Json.Tests/JsonTextWriterTest.cs b/Src/Newtonsoft.Json.Tests/JsonTextWriterTest.cs
index 788be268..66c1c9e8 100644
--- a/Src/Newtonsoft.Json.Tests/JsonTextWriterTest.cs
+++ b/Src/Newtonsoft.Json.Tests/JsonTextWriterTest.cs
@@ -466,5 +466,71 @@ namespace Newtonsoft.Json.Tests
Assert.AreEqual(@"[0.0,0.0,0.1,1.0,1.000001,1E-06,4.94065645841247E-324,Infinity,-Infinity,NaN,1.7976931348623157E+308,-1.7976931348623157E+308,Infinity,-Infinity,NaN]", sb.ToString());
}
+
+ [Test]
+ [ExpectedException(typeof(JsonWriterException), ExpectedMessage = "No token to close.")]
+ public void BadWriteEndArray()
+ {
+ StringBuilder sb = new StringBuilder();
+ StringWriter sw = new StringWriter(sb);
+
+ using (JsonWriter jsonWriter = new JsonTextWriter(sw))
+ {
+ jsonWriter.WriteStartArray();
+
+ jsonWriter.WriteValue(0.0);
+
+ jsonWriter.WriteEndArray();
+ jsonWriter.WriteEndArray();
+ }
+ }
+
+ [Test]
+ [ExpectedException(typeof(ArgumentException), ExpectedMessage = @"Invalid JavaScript string quote character. Valid quote characters are ' and "".")]
+ public void InvalidQuoteChar()
+ {
+ StringBuilder sb = new StringBuilder();
+ StringWriter sw = new StringWriter(sb);
+
+ using (JsonTextWriter jsonWriter = new JsonTextWriter(sw))
+ {
+ jsonWriter.Formatting = Formatting.Indented;
+ jsonWriter.QuoteChar = '*';
+ }
+ }
+
+ [Test]
+ public void Indentation()
+ {
+ StringBuilder sb = new StringBuilder();
+ StringWriter sw = new StringWriter(sb);
+
+ using (JsonTextWriter jsonWriter = new JsonTextWriter(sw))
+ {
+ jsonWriter.Formatting = Formatting.Indented;
+ Assert.AreEqual(Formatting.Indented, jsonWriter.Formatting);
+
+ jsonWriter.Indentation = 5;
+ Assert.AreEqual(5, jsonWriter.Indentation);
+ jsonWriter.IndentChar = '_';
+ Assert.AreEqual('_', jsonWriter.IndentChar);
+ jsonWriter.QuoteName = true;
+ Assert.AreEqual(true, jsonWriter.QuoteName);
+ jsonWriter.QuoteChar = '\'';
+ Assert.AreEqual('\'', jsonWriter.QuoteChar);
+
+ jsonWriter.WriteStartObject();
+ jsonWriter.WritePropertyName("propertyName");
+ jsonWriter.WriteValue(double.NaN);
+ jsonWriter.WriteEndObject();
+ }
+
+ string expected = @"{
+_____'propertyName': NaN
+}";
+ string result = sb.ToString();
+
+ Assert.AreEqual(expected, result);
+ }
}
}
\ No newline at end of file
diff --git a/Src/Newtonsoft.Json.Tests/Newtonsoft.Json.Tests.Compact.csproj b/Src/Newtonsoft.Json.Tests/Newtonsoft.Json.Tests.Compact.csproj
index c61b752e..f34c4f53 100644
--- a/Src/Newtonsoft.Json.Tests/Newtonsoft.Json.Tests.Compact.csproj
+++ b/Src/Newtonsoft.Json.Tests/Newtonsoft.Json.Tests.Compact.csproj
@@ -68,6 +68,7 @@
+
diff --git a/Src/Newtonsoft.Json.Tests/Newtonsoft.Json.Tests.Silverlight.csproj b/Src/Newtonsoft.Json.Tests/Newtonsoft.Json.Tests.Silverlight.csproj
index d82e0a0d..a20396dc 100644
--- a/Src/Newtonsoft.Json.Tests/Newtonsoft.Json.Tests.Silverlight.csproj
+++ b/Src/Newtonsoft.Json.Tests/Newtonsoft.Json.Tests.Silverlight.csproj
@@ -72,6 +72,7 @@
+
diff --git a/Src/Newtonsoft.Json.Tests/Newtonsoft.Json.Tests.csproj b/Src/Newtonsoft.Json.Tests/Newtonsoft.Json.Tests.csproj
index 4b0eabe3..92a6fa2f 100644
--- a/Src/Newtonsoft.Json.Tests/Newtonsoft.Json.Tests.csproj
+++ b/Src/Newtonsoft.Json.Tests/Newtonsoft.Json.Tests.csproj
@@ -86,6 +86,13 @@
+
+ True
+ True
+ FileSystemEntityModel.edmx
+
+
+
@@ -98,6 +105,7 @@
+
@@ -201,6 +209,10 @@
+
+ EntityModelCodeGenerator
+ FileSystemEntityModel.Designer.cs
+ LinqToSqlClasses.dbml
diff --git a/Src/Newtonsoft.Json.Tests/Serialization/EntitiesSerializationTests.cs b/Src/Newtonsoft.Json.Tests/Serialization/EntitiesSerializationTests.cs
new file mode 100644
index 00000000..5c40037d
--- /dev/null
+++ b/Src/Newtonsoft.Json.Tests/Serialization/EntitiesSerializationTests.cs
@@ -0,0 +1,314 @@
+#region License
+// Copyright (c) 2007 James Newton-King
+//
+// Permission is hereby granted, free of charge, to any person
+// obtaining a copy of this software and associated documentation
+// files (the "Software"), to deal in the Software without
+// restriction, including without limitation the rights to use,
+// copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following
+// conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+// OTHER DEALINGS IN THE SOFTWARE.
+#endregion
+
+#if !PocketPC && !SILVERLIGHT
+using System;
+using System.Collections.Generic;
+using System.Data;
+using System.Linq;
+using System.Text;
+using Newtonsoft.Json.Converters;
+using NUnit.Framework;
+
+namespace Newtonsoft.Json.Tests.Serialization
+{
+ public class EntitiesSerializationTests : TestFixtureBase
+ {
+ [Test]
+ public void SerializeEntity()
+ {
+ Folder rootFolder = CreateEntitiesTestData();
+
+ string json = JsonConvert.SerializeObject(rootFolder, Formatting.Indented, new IsoDateTimeConverter());
+
+ string expected = @"{
+ ""$id"": ""1"",
+ ""FolderId"": ""a4e8ba80-eb24-4591-bb1c-62d3ad83701e"",
+ ""Name"": ""Root folder"",
+ ""Description"": ""Description!"",
+ ""CreatedDate"": ""2000-12-10T10:50:00Z"",
+ ""Files"": [],
+ ""ChildFolders"": [
+ {
+ ""$id"": ""2"",
+ ""FolderId"": ""484936e2-7cbb-4592-93ff-b2103e5705e4"",
+ ""Name"": ""Child folder"",
+ ""Description"": ""Description!"",
+ ""CreatedDate"": ""2001-11-20T10:50:00Z"",
+ ""Files"": [
+ {
+ ""$id"": ""3"",
+ ""FileId"": ""cc76d734-49f1-4616-bb38-41514228ac6c"",
+ ""Name"": ""File 1"",
+ ""Description"": ""Description!"",
+ ""CreatedDate"": ""2002-10-30T10:50:00Z"",
+ ""Folder"": {
+ ""$ref"": ""2""
+ },
+ ""EntityKey"": {
+ ""$id"": ""4"",
+ ""EntitySetName"": ""File"",
+ ""EntityContainerName"": ""DataServicesTestDatabaseEntities"",
+ ""EntityKeyValues"": [
+ {
+ ""Key"": ""FileId"",
+ ""Type"": ""System.Guid"",
+ ""Value"": ""cc76d734-49f1-4616-bb38-41514228ac6c""
+ }
+ ]
+ }
+ }
+ ],
+ ""ChildFolders"": [],
+ ""ParentFolder"": {
+ ""$ref"": ""1""
+ },
+ ""EntityKey"": {
+ ""$id"": ""5"",
+ ""EntitySetName"": ""Folder"",
+ ""EntityContainerName"": ""DataServicesTestDatabaseEntities"",
+ ""EntityKeyValues"": [
+ {
+ ""Key"": ""FolderId"",
+ ""Type"": ""System.Guid"",
+ ""Value"": ""484936e2-7cbb-4592-93ff-b2103e5705e4""
+ }
+ ]
+ }
+ }
+ ],
+ ""ParentFolder"": null,
+ ""EntityKey"": {
+ ""$id"": ""6"",
+ ""EntitySetName"": ""Folder"",
+ ""EntityContainerName"": ""DataServicesTestDatabaseEntities"",
+ ""EntityKeyValues"": [
+ {
+ ""Key"": ""FolderId"",
+ ""Type"": ""System.Guid"",
+ ""Value"": ""a4e8ba80-eb24-4591-bb1c-62d3ad83701e""
+ }
+ ]
+ }
+}";
+
+ Assert.AreEqual(expected, json);
+ }
+
+ [Test]
+ public void DeserializeEntity()
+ {
+ string json = @"{
+ ""$id"": ""1"",
+ ""FolderId"": ""a4e8ba80-eb24-4591-bb1c-62d3ad83701e"",
+ ""Name"": ""Root folder"",
+ ""Description"": ""Description!"",
+ ""CreatedDate"": ""2000-12-10T10:50:00Z"",
+ ""Files"": [],
+ ""ChildFolders"": [
+ {
+ ""$id"": ""2"",
+ ""FolderId"": ""484936e2-7cbb-4592-93ff-b2103e5705e4"",
+ ""Name"": ""Child folder"",
+ ""Description"": ""Description!"",
+ ""CreatedDate"": ""2001-11-20T10:50:00Z"",
+ ""Files"": [
+ {
+ ""$id"": ""3"",
+ ""FileId"": ""cc76d734-49f1-4616-bb38-41514228ac6c"",
+ ""Name"": ""File 1"",
+ ""Description"": ""Description!"",
+ ""CreatedDate"": ""2002-10-30T10:50:00Z"",
+ ""Folder"": {
+ ""$ref"": ""2""
+ },
+ ""EntityKey"": {
+ ""$id"": ""4"",
+ ""EntitySetName"": ""File"",
+ ""EntityContainerName"": ""DataServicesTestDatabaseEntities"",
+ ""EntityKeyValues"": [
+ {
+ ""Key"": ""FileId"",
+ ""Type"": ""System.Guid"",
+ ""Value"": ""cc76d734-49f1-4616-bb38-41514228ac6c""
+ }
+ ]
+ }
+ }
+ ],
+ ""ChildFolders"": [],
+ ""ParentFolder"": {
+ ""$ref"": ""1""
+ },
+ ""EntityKey"": {
+ ""$id"": ""5"",
+ ""EntitySetName"": ""Folder"",
+ ""EntityContainerName"": ""DataServicesTestDatabaseEntities"",
+ ""EntityKeyValues"": [
+ {
+ ""Key"": ""FolderId"",
+ ""Type"": ""System.Guid"",
+ ""Value"": ""484936e2-7cbb-4592-93ff-b2103e5705e4""
+ }
+ ]
+ }
+ }
+ ],
+ ""ParentFolder"": null,
+ ""EntityKey"": {
+ ""$id"": ""6"",
+ ""EntitySetName"": ""Folder"",
+ ""EntityContainerName"": ""DataServicesTestDatabaseEntities"",
+ ""EntityKeyValues"": [
+ {
+ ""Key"": ""FolderId"",
+ ""Type"": ""System.Guid"",
+ ""Value"": ""a4e8ba80-eb24-4591-bb1c-62d3ad83701e""
+ }
+ ]
+ }
+}";
+
+ Folder f = JsonConvert.DeserializeObject(json, new IsoDateTimeConverter());
+
+ Assert.IsNotNull(f);
+ Assert.AreEqual(new Guid("A4E8BA80-EB24-4591-BB1C-62D3AD83701E"), f.FolderId);
+ Assert.AreEqual("Folder", f.EntityKey.EntitySetName);
+ Assert.AreEqual("DataServicesTestDatabaseEntities", f.EntityKey.EntityContainerName);
+ Assert.AreEqual("Folder", f.EntityKey.EntitySetName);
+ Assert.AreEqual(false, f.EntityKey.IsTemporary);
+ Assert.AreEqual(1, f.EntityKey.EntityKeyValues.Length);
+ Assert.AreEqual("FolderId", f.EntityKey.EntityKeyValues[0].Key);
+ Assert.AreEqual(new Guid("A4E8BA80-EB24-4591-BB1C-62D3AD83701E"), f.EntityKey.EntityKeyValues[0].Value);
+ Assert.AreEqual("Root folder", f.Name);
+ Assert.AreEqual(new DateTime(2000, 12, 10, 10, 50, 0, DateTimeKind.Utc), f.CreatedDate);
+ Assert.AreEqual(null, f.ParentFolder);
+ Assert.AreEqual(1, f.ChildFolders.Count);
+
+ Folder childFolder = f.ChildFolders.ElementAt(0);
+
+ Assert.AreEqual("Child folder", childFolder.Name);
+ Assert.AreEqual("Description!", childFolder.Description);
+ Assert.AreEqual(f, childFolder.ParentFolder);
+ Assert.AreEqual(f, childFolder.ParentFolderReference.Value);
+ // is this a problem?
+ Assert.AreEqual(null, childFolder.ParentFolderReference.EntityKey);
+ }
+
+ [Test]
+ public void SerializeMultiValueEntityKey()
+ {
+ EntityKey e = new EntityKey("DataServicesTestDatabaseEntities.Folder",
+ new List
+ {
+ new EntityKeyMember("GuidId", new Guid("A4E8BA80-EB24-4591-BB1C-62D3AD83701E")),
+ new EntityKeyMember("IntId", int.MaxValue),
+ new EntityKeyMember("LongId", long.MaxValue),
+ new EntityKeyMember("StringId", "String!"),
+ new EntityKeyMember("DateTimeId", new DateTime(2000, 12, 10, 10, 50, 0, DateTimeKind.Utc))
+ });
+
+ string json = JsonConvert.SerializeObject(e, Formatting.Indented);
+
+ Assert.AreEqual(@"{
+ ""$id"": ""1"",
+ ""EntitySetName"": ""Folder"",
+ ""EntityContainerName"": ""DataServicesTestDatabaseEntities"",
+ ""EntityKeyValues"": [
+ {
+ ""Key"": ""GuidId"",
+ ""Type"": ""System.Guid"",
+ ""Value"": ""a4e8ba80-eb24-4591-bb1c-62d3ad83701e""
+ },
+ {
+ ""Key"": ""IntId"",
+ ""Type"": ""System.Int32"",
+ ""Value"": ""2147483647""
+ },
+ {
+ ""Key"": ""LongId"",
+ ""Type"": ""System.Int64"",
+ ""Value"": ""9223372036854775807""
+ },
+ {
+ ""Key"": ""StringId"",
+ ""Type"": ""System.String"",
+ ""Value"": ""String!""
+ },
+ {
+ ""Key"": ""DateTimeId"",
+ ""Type"": ""System.DateTime"",
+ ""Value"": ""12/10/2000 10:50:00""
+ }
+ ]
+}", json);
+
+ EntityKey newKey = JsonConvert.DeserializeObject(json);
+ Assert.IsFalse(ReferenceEquals(e, newKey));
+
+ Assert.AreEqual(5, newKey.EntityKeyValues.Length);
+ Assert.AreEqual("GuidId", newKey.EntityKeyValues[0].Key);
+ Assert.AreEqual(new Guid("A4E8BA80-EB24-4591-BB1C-62D3AD83701E"), newKey.EntityKeyValues[0].Value);
+ Assert.AreEqual("IntId", newKey.EntityKeyValues[1].Key);
+ Assert.AreEqual(int.MaxValue, newKey.EntityKeyValues[1].Value);
+ Assert.AreEqual("LongId", newKey.EntityKeyValues[2].Key);
+ Assert.AreEqual(long.MaxValue, newKey.EntityKeyValues[2].Value);
+ Assert.AreEqual("StringId", newKey.EntityKeyValues[3].Key);
+ Assert.AreEqual("String!", newKey.EntityKeyValues[3].Value);
+ Assert.AreEqual("DateTimeId", newKey.EntityKeyValues[4].Key);
+ Assert.AreEqual(new DateTime(2000, 12, 10, 10, 50, 0, DateTimeKind.Utc), newKey.EntityKeyValues[4].Value);
+ }
+
+ private Folder CreateEntitiesTestData()
+ {
+ Folder folder = new Folder();
+ folder.FolderId = new Guid("A4E8BA80-EB24-4591-BB1C-62D3AD83701E");
+ folder.EntityKey = new EntityKey("DataServicesTestDatabaseEntities.Folder", "FolderId", folder.FolderId);
+ folder.Name = "Root folder";
+ folder.Description = "Description!";
+ folder.CreatedDate = new DateTime(2000, 12, 10, 10, 50, 0, DateTimeKind.Utc);
+
+ Folder childFolder = new Folder();
+ childFolder.FolderId = new Guid("484936E2-7CBB-4592-93FF-B2103E5705E4");
+ childFolder.EntityKey = new EntityKey("DataServicesTestDatabaseEntities.Folder", "FolderId", childFolder.FolderId);
+ childFolder.Name = "Child folder";
+ childFolder.Description = "Description!";
+ childFolder.CreatedDate = new DateTime(2001, 11, 20, 10, 50, 0, DateTimeKind.Utc);
+
+ folder.ChildFolders.Add(childFolder);
+
+ File file1 = new File();
+ file1.FileId = new Guid("CC76D734-49F1-4616-BB38-41514228AC6C");
+ file1.EntityKey = new EntityKey("DataServicesTestDatabaseEntities.File", "FileId", file1.FileId);
+ file1.Name = "File 1";
+ file1.Description = "Description!";
+ file1.CreatedDate = new DateTime(2002, 10, 30, 10, 50, 0, DateTimeKind.Utc);
+
+ childFolder.Files.Add(file1);
+ return folder;
+ }
+ }
+}
+#endif
\ No newline at end of file
diff --git a/Src/Newtonsoft.Json.sln b/Src/Newtonsoft.Json.sln
index 8c1a1b8f..e5baa538 100644
--- a/Src/Newtonsoft.Json.sln
+++ b/Src/Newtonsoft.Json.sln
@@ -24,6 +24,7 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Doc", "Doc", "{8F9E13D9-418
Doc\LINQtoJSON.html = Doc\LINQtoJSON.html
Doc\PreserveObjectReferences.html = Doc\PreserveObjectReferences.html
Doc\ReadingWritingJSON.html = Doc\ReadingWritingJSON.html
+ Doc\SerializationAttributes.html = Doc\SerializationAttributes.html
Doc\SerializationCallbacks.html = Doc\SerializationCallbacks.html
Doc\SerializingJSON.html = Doc\SerializingJSON.html
Doc\styles.css = Doc\styles.css
diff --git a/Src/Newtonsoft.Json/Converters/EntityKeyMemberConverter.cs b/Src/Newtonsoft.Json/Converters/EntityKeyMemberConverter.cs
new file mode 100644
index 00000000..84943966
--- /dev/null
+++ b/Src/Newtonsoft.Json/Converters/EntityKeyMemberConverter.cs
@@ -0,0 +1,112 @@
+#region License
+// Copyright (c) 2007 James Newton-King
+//
+// Permission is hereby granted, free of charge, to any person
+// obtaining a copy of this software and associated documentation
+// files (the "Software"), to deal in the Software without
+// restriction, including without limitation the rights to use,
+// copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following
+// conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+// OTHER DEALINGS IN THE SOFTWARE.
+#endregion
+
+#if !PocketPC && !SILVERLIGHT
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Data;
+using Newtonsoft.Json.Serialization;
+using System.Globalization;
+using Newtonsoft.Json.Utilities;
+
+namespace Newtonsoft.Json.Converters
+{
+ public class EntityKeyMemberConverter : JsonConverter
+ {
+ public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
+ {
+ EntityKeyMember entityKeyMember = (EntityKeyMember) value;
+ Type keyType = (entityKeyMember.Value != null) ? entityKeyMember.Value.GetType() : null;
+
+ writer.WriteStartObject();
+ writer.WritePropertyName("Key");
+ writer.WriteValue(entityKeyMember.Key);
+ writer.WritePropertyName("Type");
+ writer.WriteValue((keyType != null) ? keyType.FullName : null);
+
+ writer.WritePropertyName("Value");
+
+ if (keyType != null)
+ {
+ string valueJson;
+ if (JsonSerializerWriter.TryConvertToString(entityKeyMember.Value, keyType, out valueJson))
+ writer.WriteValue(valueJson);
+ else
+ writer.WriteValue(entityKeyMember.Value);
+ }
+ else
+ {
+ writer.WriteNull();
+ }
+
+ writer.WriteEndObject();
+ }
+
+ private static void ReadAndAssertProperty(JsonReader reader, string propertyName)
+ {
+ ReadAndAssert(reader);
+
+ if (reader.TokenType != JsonToken.PropertyName || reader.Value.ToString() != propertyName)
+ throw new JsonSerializationException("Expected JSON property '{0}'.".FormatWith(CultureInfo.InvariantCulture, propertyName));
+ }
+
+ private static void ReadAndAssert(JsonReader reader)
+ {
+ if (!reader.Read())
+ throw new JsonSerializationException("Unexpected end.");
+ }
+
+ public override object ReadJson(JsonReader reader, Type objectType, JsonSerializer serializer)
+ {
+ EntityKeyMember entityKeyMember = new EntityKeyMember();
+
+ ReadAndAssertProperty(reader, "Key");
+ ReadAndAssert(reader);
+ entityKeyMember.Key = reader.Value.ToString();
+
+ ReadAndAssertProperty(reader, "Type");
+ ReadAndAssert(reader);
+ string type = reader.Value.ToString();
+
+ Type t = Type.GetType(type);
+
+ ReadAndAssertProperty(reader, "Value");
+ ReadAndAssert(reader);
+ entityKeyMember.Value = serializer.Deserialize(reader, t);
+
+ ReadAndAssert(reader);
+
+ return entityKeyMember;
+ }
+
+ public override bool CanConvert(Type objectType)
+ {
+ return typeof(EntityKeyMember).IsAssignableFrom(objectType);
+ }
+ }
+}
+#endif
\ No newline at end of file
diff --git a/Src/Newtonsoft.Json/JsonSerializer.cs b/Src/Newtonsoft.Json/JsonSerializer.cs
index 90f739a2..3fb5503b 100644
--- a/Src/Newtonsoft.Json/JsonSerializer.cs
+++ b/Src/Newtonsoft.Json/JsonSerializer.cs
@@ -26,6 +26,7 @@
using System;
using System.Collections.Generic;
using System.IO;
+using Newtonsoft.Json.Converters;
using Newtonsoft.Json.Serialization;
using Newtonsoft.Json.Utilities;
using System.Runtime.Serialization;
@@ -51,6 +52,13 @@ namespace Newtonsoft.Json
private IReferenceResolver _referenceResolver;
private SerializationBinder _binder;
+ private static readonly IList BuiltInConverters = new List
+ {
+#if !PocketPC && !SILVERLIGHT
+ new EntityKeyMemberConverter()
+#endif
+ };
+
///
/// Gets or sets the used by the serializer when resolving references.
///
@@ -388,7 +396,12 @@ namespace Newtonsoft.Json
internal bool HasMatchingConverter(Type type, out JsonConverter matchingConverter)
{
- return HasMatchingConverter(_converters, type, out matchingConverter);
+ if (HasMatchingConverter(_converters, type, out matchingConverter))
+ return true;
+ if (HasMatchingConverter(BuiltInConverters, type, out matchingConverter))
+ return true;
+
+ return false;
}
internal static bool HasMatchingConverter(IList converters, Type objectType, out JsonConverter matchingConverter)
diff --git a/Src/Newtonsoft.Json/Newtonsoft.Json.Compact.csproj b/Src/Newtonsoft.Json/Newtonsoft.Json.Compact.csproj
index 17138bcf..09b9b7ff 100644
--- a/Src/Newtonsoft.Json/Newtonsoft.Json.Compact.csproj
+++ b/Src/Newtonsoft.Json/Newtonsoft.Json.Compact.csproj
@@ -57,6 +57,7 @@
+
diff --git a/Src/Newtonsoft.Json/Newtonsoft.Json.Silverlight.csproj b/Src/Newtonsoft.Json/Newtonsoft.Json.Silverlight.csproj
index 04529031..4d9d40b4 100644
--- a/Src/Newtonsoft.Json/Newtonsoft.Json.Silverlight.csproj
+++ b/Src/Newtonsoft.Json/Newtonsoft.Json.Silverlight.csproj
@@ -51,6 +51,7 @@
+
diff --git a/Src/Newtonsoft.Json/Newtonsoft.Json.csproj b/Src/Newtonsoft.Json/Newtonsoft.Json.csproj
index 656fb244..52e826ee 100644
--- a/Src/Newtonsoft.Json/Newtonsoft.Json.csproj
+++ b/Src/Newtonsoft.Json/Newtonsoft.Json.csproj
@@ -72,6 +72,9 @@
3.5
+
+ 3.5
+ 3.5
@@ -85,6 +88,7 @@
+
@@ -205,5 +209,8 @@
false
+
+
+
\ No newline at end of file
diff --git a/Src/Newtonsoft.Json/Serialization/DefaultContractResolver.cs b/Src/Newtonsoft.Json/Serialization/DefaultContractResolver.cs
index 67554426..9a71bb16 100644
--- a/Src/Newtonsoft.Json/Serialization/DefaultContractResolver.cs
+++ b/Src/Newtonsoft.Json/Serialization/DefaultContractResolver.cs
@@ -28,9 +28,13 @@ using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Globalization;
+using System.Linq;
using System.Reflection;
using System.Runtime.Serialization;
using Newtonsoft.Json.Utilities;
+#if !PocketPC && !SILVERLIGHT
+using System.Data.Objects.DataClasses;
+#endif
namespace Newtonsoft.Json.Serialization
{
@@ -101,9 +105,29 @@ namespace Newtonsoft.Json.Serialization
}
}
+#if !PocketPC && !SILVERLIGHT
+ // don't include EntityKey on entities objects... this is a bit hacky
+ if (typeof(EntityObject).IsAssignableFrom(objectType))
+ serializableMembers = serializableMembers.Where(ShouldSerializeEntityMember).ToList();
+#endif
+
return serializableMembers;
}
+#if !PocketPC && !SILVERLIGHT
+ private bool ShouldSerializeEntityMember(MemberInfo memberInfo)
+ {
+ PropertyInfo propertyInfo = memberInfo as PropertyInfo;
+ if (propertyInfo != null)
+ {
+ if (propertyInfo.PropertyType.IsGenericType && propertyInfo.PropertyType.GetGenericTypeDefinition() == typeof(EntityReference<>))
+ return false;
+ }
+
+ return true;
+ }
+#endif
+
///
/// Creates a for the given type.
///
@@ -124,7 +148,18 @@ namespace Newtonsoft.Json.Serialization
{
JsonContainerAttribute containerAttribute = JsonTypeReflector.GetJsonContainerAttribute(contract.UnderlyingType);
if (containerAttribute != null)
+ {
contract.IsReference = containerAttribute._isReference;
+ }
+#if !PocketPC
+ else
+ {
+ DataContractAttribute dataContractAttribute = JsonTypeReflector.GetDataContractAttribute(contract.UnderlyingType);
+ // doesn't have a null value
+ if (dataContractAttribute != null && dataContractAttribute.IsReference)
+ contract.IsReference = true;
+ }
+#endif
#if !PocketPC && !SILVERLIGHT
foreach (MethodInfo method in contract.UnderlyingType.GetMethods(BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly))
diff --git a/Src/Newtonsoft.Json/Serialization/JsonSerializerReader.cs b/Src/Newtonsoft.Json/Serialization/JsonSerializerReader.cs
index 2b1231e1..1f3a5a5b 100644
--- a/Src/Newtonsoft.Json/Serialization/JsonSerializerReader.cs
+++ b/Src/Newtonsoft.Json/Serialization/JsonSerializerReader.cs
@@ -88,7 +88,7 @@ namespace Newtonsoft.Json.Serialization
if (reader == null)
throw new ArgumentNullException("reader");
- if (!reader.Read())
+ if (reader.TokenType == JsonToken.None && !reader.Read())
return null;
return CreateValue(reader, objectType, null, null);
diff --git a/Src/Newtonsoft.Json/Serialization/JsonSerializerWriter.cs b/Src/Newtonsoft.Json/Serialization/JsonSerializerWriter.cs
index 1f32c624..27e6498e 100644
--- a/Src/Newtonsoft.Json/Serialization/JsonSerializerWriter.cs
+++ b/Src/Newtonsoft.Json/Serialization/JsonSerializerWriter.cs
@@ -230,32 +230,47 @@ namespace Newtonsoft.Json.Serialization
writer.WriteEndObject();
}
- private void SerializeObject(JsonWriter writer, object value, JsonObjectContract contract)
+ internal static bool TryConvertToString(object value, Type type, out string s)
{
- contract.InvokeOnSerializing(value);
-
#if !SILVERLIGHT && !PocketPC
- TypeConverter converter = TypeDescriptor.GetConverter(contract.UnderlyingType);
+ TypeConverter converter = TypeDescriptor.GetConverter(type);
// use the objectType's TypeConverter if it has one and can convert to a string
- if (converter != null && !(converter is ComponentConverter) && (converter.GetType() != typeof (TypeConverter) || value is Type))
+ if (converter != null && !(converter is ComponentConverter) && (converter.GetType() != typeof(TypeConverter) || value is Type))
{
- if (converter.CanConvertTo(typeof (string)))
+ if (converter.CanConvertTo(typeof(string)))
{
- writer.WriteValue(converter.ConvertToInvariantString(value));
-
- contract.InvokeOnSerialized(value);
- return;
+ s = converter.ConvertToInvariantString(value);
+ return true;
}
}
#else
if (value is Guid || value is Type || value is Uri)
{
- writer.WriteValue(value.ToString());
- return;
+ s = value.ToString();
+ return true;
}
#endif
+ s = null;
+ return false;
+ }
+
+ private void SerializeObject(JsonWriter writer, object value, JsonObjectContract contract)
+ {
+ contract.InvokeOnSerializing(value);
+
+ string s;
+ if (TryConvertToString(value, contract.UnderlyingType, out s))
+ {
+ writer.WriteValue(s);
+
+#if !SILVERLIGHT && !PocketPC
+ contract.InvokeOnSerialized(value);
+#endif
+ return;
+ }
+
SerializeStack.Add(value);
writer.WriteStartObject();