-Changed serializer to better work with ICollection<T> when deserializing
-Improved serializer caching of static type data
This commit is contained in:
+242
@@ -0,0 +1,242 @@
|
||||
//------------------------------------------------------------------------------
|
||||
// <auto-generated>
|
||||
// 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.
|
||||
// </auto-generated>
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
[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
|
||||
{
|
||||
|
||||
/// <summary>
|
||||
/// There are no comments for EntityDataModelContainer in the schema.
|
||||
/// </summary>
|
||||
public partial class EntityDataModelContainer : global::System.Data.Objects.ObjectContext
|
||||
{
|
||||
/// <summary>
|
||||
/// Initializes a new EntityDataModelContainer object using the connection string found in the 'EntityDataModelContainer' section of the application configuration file.
|
||||
/// </summary>
|
||||
public EntityDataModelContainer() :
|
||||
base("name=EntityDataModelContainer", "EntityDataModelContainer")
|
||||
{
|
||||
this.OnContextCreated();
|
||||
}
|
||||
/// <summary>
|
||||
/// Initialize a new EntityDataModelContainer object.
|
||||
/// </summary>
|
||||
public EntityDataModelContainer(string connectionString) :
|
||||
base(connectionString, "EntityDataModelContainer")
|
||||
{
|
||||
this.OnContextCreated();
|
||||
}
|
||||
/// <summary>
|
||||
/// Initialize a new EntityDataModelContainer object.
|
||||
/// </summary>
|
||||
public EntityDataModelContainer(global::System.Data.EntityClient.EntityConnection connection) :
|
||||
base(connection, "EntityDataModelContainer")
|
||||
{
|
||||
this.OnContextCreated();
|
||||
}
|
||||
partial void OnContextCreated();
|
||||
/// <summary>
|
||||
/// There are no comments for PurchaseSet in the schema.
|
||||
/// </summary>
|
||||
public global::System.Data.Objects.ObjectQuery<Purchase> PurchaseSet
|
||||
{
|
||||
get
|
||||
{
|
||||
if ((this._PurchaseSet == null))
|
||||
{
|
||||
this._PurchaseSet = base.CreateQuery<Purchase>("[PurchaseSet]");
|
||||
}
|
||||
return this._PurchaseSet;
|
||||
}
|
||||
}
|
||||
private global::System.Data.Objects.ObjectQuery<Purchase> _PurchaseSet;
|
||||
/// <summary>
|
||||
/// There are no comments for PurchaseLineSet in the schema.
|
||||
/// </summary>
|
||||
public global::System.Data.Objects.ObjectQuery<PurchaseLine> PurchaseLineSet
|
||||
{
|
||||
get
|
||||
{
|
||||
if ((this._PurchaseLineSet == null))
|
||||
{
|
||||
this._PurchaseLineSet = base.CreateQuery<PurchaseLine>("[PurchaseLineSet]");
|
||||
}
|
||||
return this._PurchaseLineSet;
|
||||
}
|
||||
}
|
||||
private global::System.Data.Objects.ObjectQuery<PurchaseLine> _PurchaseLineSet;
|
||||
/// <summary>
|
||||
/// There are no comments for PurchaseSet in the schema.
|
||||
/// </summary>
|
||||
public void AddToPurchaseSet(Purchase purchase)
|
||||
{
|
||||
base.AddObject("PurchaseSet", purchase);
|
||||
}
|
||||
/// <summary>
|
||||
/// There are no comments for PurchaseLineSet in the schema.
|
||||
/// </summary>
|
||||
public void AddToPurchaseLineSet(PurchaseLine purchaseLine)
|
||||
{
|
||||
base.AddObject("PurchaseLineSet", purchaseLine);
|
||||
}
|
||||
}
|
||||
/// <summary>
|
||||
/// There are no comments for EntityDataModel.Purchase in the schema.
|
||||
/// </summary>
|
||||
/// <KeyProperties>
|
||||
/// Id
|
||||
/// </KeyProperties>
|
||||
[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
|
||||
{
|
||||
/// <summary>
|
||||
/// Create a new Purchase object.
|
||||
/// </summary>
|
||||
/// <param name="id">Initial value of Id.</param>
|
||||
public static Purchase CreatePurchase(int id)
|
||||
{
|
||||
Purchase purchase = new Purchase();
|
||||
purchase.Id = id;
|
||||
return purchase;
|
||||
}
|
||||
/// <summary>
|
||||
/// There are no comments for Property Id in the schema.
|
||||
/// </summary>
|
||||
[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();
|
||||
/// <summary>
|
||||
/// There are no comments for PurchaseLine in the schema.
|
||||
/// </summary>
|
||||
[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> PurchaseLine
|
||||
{
|
||||
get
|
||||
{
|
||||
return ((global::System.Data.Objects.DataClasses.IEntityWithRelationships)(this)).RelationshipManager.GetRelatedCollection<PurchaseLine>("EntityDataModel.PurchasePurchaseLine", "PurchaseLine");
|
||||
}
|
||||
set
|
||||
{
|
||||
if ((value != null))
|
||||
{
|
||||
((global::System.Data.Objects.DataClasses.IEntityWithRelationships)(this)).RelationshipManager.InitializeRelatedCollection<PurchaseLine>("EntityDataModel.PurchasePurchaseLine", "PurchaseLine", value);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
/// <summary>
|
||||
/// There are no comments for EntityDataModel.PurchaseLine in the schema.
|
||||
/// </summary>
|
||||
/// <KeyProperties>
|
||||
/// Id
|
||||
/// </KeyProperties>
|
||||
[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
|
||||
{
|
||||
/// <summary>
|
||||
/// Create a new PurchaseLine object.
|
||||
/// </summary>
|
||||
/// <param name="id">Initial value of Id.</param>
|
||||
public static PurchaseLine CreatePurchaseLine(int id)
|
||||
{
|
||||
PurchaseLine purchaseLine = new PurchaseLine();
|
||||
purchaseLine.Id = id;
|
||||
return purchaseLine;
|
||||
}
|
||||
/// <summary>
|
||||
/// There are no comments for Property Id in the schema.
|
||||
/// </summary>
|
||||
[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();
|
||||
/// <summary>
|
||||
/// There are no comments for Purchase in the schema.
|
||||
/// </summary>
|
||||
[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<Purchase>("EntityDataModel.PurchasePurchaseLine", "Purchase").Value;
|
||||
}
|
||||
set
|
||||
{
|
||||
((global::System.Data.Objects.DataClasses.IEntityWithRelationships)(this)).RelationshipManager.GetRelatedReference<Purchase>("EntityDataModel.PurchasePurchaseLine", "Purchase").Value = value;
|
||||
}
|
||||
}
|
||||
/// <summary>
|
||||
/// There are no comments for Purchase in the schema.
|
||||
/// </summary>
|
||||
[global::System.ComponentModel.BrowsableAttribute(false)]
|
||||
[global::System.Runtime.Serialization.DataMemberAttribute()]
|
||||
public global::System.Data.Objects.DataClasses.EntityReference<Purchase> PurchaseReference
|
||||
{
|
||||
get
|
||||
{
|
||||
return ((global::System.Data.Objects.DataClasses.IEntityWithRelationships)(this)).RelationshipManager.GetRelatedReference<Purchase>("EntityDataModel.PurchasePurchaseLine", "Purchase");
|
||||
}
|
||||
set
|
||||
{
|
||||
if ((value != null))
|
||||
{
|
||||
((global::System.Data.Objects.DataClasses.IEntityWithRelationships)(this)).RelationshipManager.InitializeRelatedReference<Purchase>("EntityDataModel.PurchasePurchaseLine", "Purchase", value);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,67 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<edmx:Edmx Version="1.0" xmlns:edmx="http://schemas.microsoft.com/ado/2007/06/edmx">
|
||||
<!-- EF Runtime content -->
|
||||
<edmx:Runtime>
|
||||
<!-- SSDL content -->
|
||||
<edmx:StorageModels>
|
||||
<Schema xmlns="http://schemas.microsoft.com/ado/2006/04/edm/ssdl" Namespace="EntityDataModel.Target" Alias="Self" Provider="System.Data.SqlClient" ProviderManifestToken="2005">
|
||||
<EntityContainer Name="EntityDataModelTargetContainer" >
|
||||
</EntityContainer>
|
||||
</Schema>
|
||||
</edmx:StorageModels>
|
||||
<!-- CSDL content -->
|
||||
<edmx:ConceptualModels>
|
||||
<Schema xmlns="http://schemas.microsoft.com/ado/2006/04/edm" Namespace="EntityDataModel" Alias="Self">
|
||||
<EntityContainer Name="EntityDataModelContainer" >
|
||||
<EntitySet Name="PurchaseSet" EntityType="EntityDataModel.Purchase" />
|
||||
<EntitySet Name="PurchaseLineSet" EntityType="EntityDataModel.PurchaseLine" />
|
||||
<AssociationSet Name="PurchasePurchaseLine" Association="EntityDataModel.PurchasePurchaseLine">
|
||||
<End Role="Purchase" EntitySet="PurchaseSet" />
|
||||
<End Role="PurchaseLine" EntitySet="PurchaseLineSet" /></AssociationSet></EntityContainer>
|
||||
<EntityType Name="Purchase">
|
||||
<Key>
|
||||
<PropertyRef Name="Id" /></Key>
|
||||
<Property Name="Id" Type="Int32" Nullable="false" />
|
||||
<NavigationProperty Name="PurchaseLine" Relationship="EntityDataModel.PurchasePurchaseLine" FromRole="Purchase" ToRole="PurchaseLine" /></EntityType>
|
||||
<EntityType Name="PurchaseLine">
|
||||
<Key>
|
||||
<PropertyRef Name="Id" /></Key>
|
||||
<Property Name="Id" Type="Int32" Nullable="false" />
|
||||
<NavigationProperty Name="Purchase" Relationship="EntityDataModel.PurchasePurchaseLine" FromRole="PurchaseLine" ToRole="Purchase" /></EntityType>
|
||||
<Association Name="PurchasePurchaseLine">
|
||||
<End Type="EntityDataModel.Purchase" Role="Purchase" Multiplicity="1" />
|
||||
<End Type="EntityDataModel.PurchaseLine" Role="PurchaseLine" Multiplicity="*" /></Association></Schema>
|
||||
</edmx:ConceptualModels>
|
||||
<!-- C-S mapping content -->
|
||||
<edmx:Mappings>
|
||||
<Mapping xmlns="urn:schemas-microsoft-com:windows:storage:mapping:CS" Space="C-S">
|
||||
<Alias Key="Model" Value="EntityDataModel" />
|
||||
<Alias Key="Target" Value="EntityDataModel.Target" />
|
||||
<EntityContainerMapping CdmEntityContainer="EntityDataModelContainer" StorageEntityContainer="EntityDataModelTargetContainer">
|
||||
</EntityContainerMapping>
|
||||
</Mapping>
|
||||
</edmx:Mappings>
|
||||
</edmx:Runtime>
|
||||
<!-- EF Designer content (DO NOT EDIT MANUALLY BELOW HERE) -->
|
||||
<edmx:Designer xmlns="http://schemas.microsoft.com/ado/2007/06/edmx">
|
||||
<edmx:Connection>
|
||||
<DesignerInfoPropertySet>
|
||||
<DesignerProperty Name="MetadataArtifactProcessing" Value="EmbedInOutputAssembly" />
|
||||
</DesignerInfoPropertySet>
|
||||
</edmx:Connection>
|
||||
<edmx:Options>
|
||||
<DesignerInfoPropertySet>
|
||||
<DesignerProperty Name="ValidateOnBuild" Value="true" />
|
||||
</DesignerInfoPropertySet>
|
||||
</edmx:Options>
|
||||
<!-- Diagram content (shape and connector positions) -->
|
||||
<edmx:Diagrams>
|
||||
<Diagram Name="EntityDataModel" >
|
||||
<EntityTypeShape EntityType="EntityDataModel.Purchase" Width="1.5" PointX="2.125" PointY="0.875" Height="1.211080729166667" />
|
||||
<EntityTypeShape EntityType="EntityDataModel.PurchaseLine" Width="1.5" PointX="3.625" PointY="3" Height="1.0187792968749996" />
|
||||
<AssociationConnector Association="EntityDataModel.PurchasePurchaseLine">
|
||||
<ConnectorPoint PointX="2.84375" PointY="2.086080729166667" />
|
||||
<ConnectorPoint PointX="2.84375" PointY="3.6055403645833333" />
|
||||
<ConnectorPoint PointX="3.625" PointY="3.6055403645833333" /></AssociationConnector></Diagram></edmx:Diagrams>
|
||||
</edmx:Designer>
|
||||
</edmx:Edmx>
|
||||
@@ -28,11 +28,77 @@ using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using Newtonsoft.Json.Utilities;
|
||||
using NUnit.Framework;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
|
||||
namespace Newtonsoft.Json.Tests
|
||||
{
|
||||
public class JavaScriptConvertTest : TestFixtureBase
|
||||
{
|
||||
#if Entities
|
||||
[Test]
|
||||
public void EntitiesTest()
|
||||
{
|
||||
Purchase purchase = new Purchase() { Id = 1 };
|
||||
purchase.PurchaseLine.Add(new PurchaseLine() { Id = 1, Purchase = purchase });
|
||||
purchase.PurchaseLine.Add(new PurchaseLine() { Id = 2, Purchase = purchase });
|
||||
|
||||
StringWriter sw = new StringWriter();
|
||||
JsonSerializer serializer = new JsonSerializer();
|
||||
serializer.ReferenceLoopHandling = ReferenceLoopHandling.Ignore;
|
||||
|
||||
using (JsonWriter jw = new JsonTextWriter(sw))
|
||||
{
|
||||
jw.Formatting = Formatting.Indented;
|
||||
|
||||
serializer.Serialize(jw, purchase);
|
||||
}
|
||||
|
||||
string json = sw.ToString();
|
||||
|
||||
Assert.AreEqual(@"{
|
||||
""Id"": 1,
|
||||
""PurchaseLine"": [
|
||||
{
|
||||
""Id"": 1,
|
||||
""PurchaseReference"": {
|
||||
""EntityKey"": null,
|
||||
""RelationshipName"": ""EntityDataModel.PurchasePurchaseLine"",
|
||||
""SourceRoleName"": ""PurchaseLine"",
|
||||
""TargetRoleName"": ""Purchase"",
|
||||
""RelationshipSet"": null,
|
||||
""IsLoaded"": false
|
||||
},
|
||||
""EntityState"": 1,
|
||||
""EntityKey"": null
|
||||
},
|
||||
{
|
||||
""Id"": 2,
|
||||
""PurchaseReference"": {
|
||||
""EntityKey"": null,
|
||||
""RelationshipName"": ""EntityDataModel.PurchasePurchaseLine"",
|
||||
""SourceRoleName"": ""PurchaseLine"",
|
||||
""TargetRoleName"": ""Purchase"",
|
||||
""RelationshipSet"": null,
|
||||
""IsLoaded"": false
|
||||
},
|
||||
""EntityState"": 1,
|
||||
""EntityKey"": null
|
||||
}
|
||||
],
|
||||
""EntityState"": 1,
|
||||
""EntityKey"": null
|
||||
}", json);
|
||||
|
||||
Purchase newPurchase = JavaScriptConvert.DeserializeObject<Purchase>(json);
|
||||
Assert.AreEqual(1, newPurchase.Id);
|
||||
|
||||
Assert.AreEqual(2, newPurchase.PurchaseLine.Count);
|
||||
Assert.AreEqual(1, newPurchase.PurchaseLine.ElementAt(0).Id);
|
||||
Assert.AreEqual(2, newPurchase.PurchaseLine.ElementAt(1).Id);
|
||||
}
|
||||
#endif
|
||||
|
||||
[Test]
|
||||
public void EscapeJavaScriptString()
|
||||
{
|
||||
|
||||
@@ -51,9 +51,13 @@
|
||||
<RequiredTargetFramework>3.5</RequiredTargetFramework>
|
||||
</Reference>
|
||||
<Reference Include="System.Data" />
|
||||
<Reference Include="System.Data.Entity">
|
||||
<RequiredTargetFramework>3.5</RequiredTargetFramework>
|
||||
</Reference>
|
||||
<Reference Include="System.Runtime.Serialization">
|
||||
<RequiredTargetFramework>3.0</RequiredTargetFramework>
|
||||
</Reference>
|
||||
<Reference Include="System.Security" />
|
||||
<Reference Include="System.ServiceModel">
|
||||
<RequiredTargetFramework>3.0</RequiredTargetFramework>
|
||||
</Reference>
|
||||
@@ -84,6 +88,7 @@
|
||||
<Compile Include="Linq\JTokenTests.cs" />
|
||||
<Compile Include="Linq\JValueTests.cs" />
|
||||
<Compile Include="Linq\LinqToJsonTest.cs" />
|
||||
<Compile Include="PerformanceTests.cs" />
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
<Compile Include="SilverlightTests.cs" />
|
||||
<Compile Include="TestFixtureBase.cs" />
|
||||
|
||||
@@ -0,0 +1,182 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.Data;
|
||||
using System.Diagnostics;
|
||||
|
||||
using Newtonsoft.Json;
|
||||
using System.IO;
|
||||
using System.Web.Script.Serialization;
|
||||
using NUnit.Framework;
|
||||
|
||||
namespace Newtonsoft.Json.Tests
|
||||
{
|
||||
/// <summary>
|
||||
/// Summary description for JsonSerializerTest
|
||||
/// </summary>
|
||||
public class PerformanceTests : TestFixtureBase
|
||||
{
|
||||
private DateTime BaseDate = DateTime.Parse("01/01/2000");
|
||||
|
||||
//JSONSerializer ser = null;
|
||||
|
||||
public string SerializeJsonNet(object value)
|
||||
{
|
||||
Type type = value.GetType();
|
||||
|
||||
Newtonsoft.Json.JsonSerializer json = new Newtonsoft.Json.JsonSerializer();
|
||||
|
||||
json.NullValueHandling = NullValueHandling.Ignore;
|
||||
|
||||
json.ObjectCreationHandling = Newtonsoft.Json.ObjectCreationHandling.Replace;
|
||||
json.MissingMemberHandling = Newtonsoft.Json.MissingMemberHandling.Ignore;
|
||||
json.ReferenceLoopHandling = ReferenceLoopHandling.Ignore;
|
||||
|
||||
|
||||
StringWriter sw = new StringWriter();
|
||||
Newtonsoft.Json.JsonTextWriter writer = new JsonTextWriter(sw);
|
||||
|
||||
if (false)
|
||||
writer.Formatting = Formatting.Indented;
|
||||
else
|
||||
writer.Formatting = Formatting.None;
|
||||
|
||||
writer.QuoteChar = '"';
|
||||
json.Serialize(writer, value);
|
||||
|
||||
string output = sw.ToString();
|
||||
writer.Close();
|
||||
|
||||
return output;
|
||||
}
|
||||
|
||||
public string SerializeWebExtensions(object value)
|
||||
{
|
||||
JavaScriptSerializer ser = new JavaScriptSerializer();
|
||||
|
||||
List<JavaScriptConverter> converters = new List<JavaScriptConverter>();
|
||||
|
||||
return ser.Serialize(value);
|
||||
}
|
||||
|
||||
|
||||
[Test]
|
||||
public void PerformanceTest2()
|
||||
{
|
||||
|
||||
TestClass test = new TestClass();
|
||||
|
||||
test.Address1.Address = "fff Street";
|
||||
test.Address1.Entered = DateTime.Now.AddDays(20);
|
||||
|
||||
test.BigNumber = 34123123123.121M;
|
||||
test.Now = DateTime.Now.AddHours(1);
|
||||
test.strings = new List<string>() { "Rick", "Markus egger ][, (2nd)", "Kevin McNeish" };
|
||||
|
||||
cAddress address = new cAddress();
|
||||
address.Entered = DateTime.Now.AddDays(-1);
|
||||
address.Address = "array address";
|
||||
|
||||
test.Addresses.Add(address);
|
||||
|
||||
address = new cAddress();
|
||||
address.Entered = DateTime.Now.AddDays(-2);
|
||||
address.Address = "array 2 address";
|
||||
test.Addresses.Add(address);
|
||||
|
||||
Stopwatch timed = new Stopwatch();
|
||||
timed.Start();
|
||||
|
||||
string json = null;
|
||||
for (int x = 0; x < 10000; x++)
|
||||
{
|
||||
json = this.SerializeJsonNet(test);
|
||||
//json = this.SerializeWebExtensions(test);
|
||||
}
|
||||
timed.Stop();
|
||||
|
||||
Console.WriteLine("{0}", timed.ElapsedMilliseconds + " ms");
|
||||
Console.WriteLine("{0}", json);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public class TestClass
|
||||
{
|
||||
|
||||
public string Name
|
||||
{
|
||||
get { return _Name; }
|
||||
set { _Name = value; }
|
||||
}
|
||||
private string _Name = "Rick";
|
||||
|
||||
|
||||
public DateTime Now
|
||||
{
|
||||
get { return _Now; }
|
||||
set { _Now = value; }
|
||||
}
|
||||
private DateTime _Now = DateTime.Now;
|
||||
|
||||
|
||||
public decimal BigNumber
|
||||
{
|
||||
get { return _BigNumber; }
|
||||
set { _BigNumber = value; }
|
||||
}
|
||||
private decimal _BigNumber = 1212121.22M;
|
||||
|
||||
|
||||
public cAddress Address1
|
||||
{
|
||||
get { return _Address1; }
|
||||
set { _Address1 = value; }
|
||||
}
|
||||
private cAddress _Address1 = new cAddress();
|
||||
|
||||
|
||||
|
||||
|
||||
public List<cAddress> Addresses
|
||||
{
|
||||
get { return _Addresses; }
|
||||
set { _Addresses = value; }
|
||||
}
|
||||
private List<cAddress> _Addresses = new List<cAddress>();
|
||||
|
||||
|
||||
public List<string> strings = new List<string>() { "Rick", "Markus", "Kevin" };
|
||||
|
||||
|
||||
public Dictionary<string, int> dictionary = new Dictionary<string, int> { { "Val asd1", 1 }, { "Val2", 3 }, { "Val3", 4 } };
|
||||
}
|
||||
|
||||
public class cAddress
|
||||
{
|
||||
|
||||
public string Address
|
||||
{
|
||||
get { return _Address; }
|
||||
set { _Address = value; }
|
||||
}
|
||||
private string _Address = "32 Kaiea";
|
||||
|
||||
|
||||
public string Phone
|
||||
{
|
||||
get { return _Phone; }
|
||||
set { _Phone = value; }
|
||||
}
|
||||
private string _Phone = "(503) 814-6335";
|
||||
|
||||
|
||||
public DateTime Entered
|
||||
{
|
||||
get { return _Entered; }
|
||||
set { _Entered = value; }
|
||||
}
|
||||
private DateTime _Entered = DateTime.Parse("01/01/2007", CultureInfo.CurrentCulture.DateTimeFormat);
|
||||
|
||||
}
|
||||
}
|
||||
@@ -36,15 +36,15 @@ namespace Newtonsoft.Json
|
||||
_converterType = converterType;
|
||||
}
|
||||
|
||||
internal JsonConverter CreateJsonConverterInstance()
|
||||
internal static JsonConverter CreateJsonConverterInstance(Type converterType)
|
||||
{
|
||||
try
|
||||
{
|
||||
return (JsonConverter)Activator.CreateInstance(_converterType);
|
||||
return (JsonConverter)Activator.CreateInstance(converterType);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
throw new Exception("Error creating {0}".FormatWith(CultureInfo.InvariantCulture, _converterType), ex);
|
||||
throw new Exception("Error creating {0}".FormatWith(CultureInfo.InvariantCulture, converterType), ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -44,13 +44,15 @@ namespace Newtonsoft.Json
|
||||
/// </summary>
|
||||
public class JsonSerializer
|
||||
{
|
||||
private static readonly Dictionary<ICustomAttributeProvider, Type> ConverterTypeCache = new Dictionary<ICustomAttributeProvider, Type>();
|
||||
private static Dictionary<Type, MemberMappingCollection> TypeMemberMappings = new Dictionary<Type,MemberMappingCollection>();
|
||||
|
||||
private ReferenceLoopHandling _referenceLoopHandling;
|
||||
private MissingMemberHandling _missingMemberHandling;
|
||||
private ObjectCreationHandling _objectCreationHandling;
|
||||
private NullValueHandling _nullValueHandling;
|
||||
private int _level;
|
||||
private JsonConverterCollection _converters;
|
||||
private Dictionary<Type, MemberMappingCollection> _typeMemberMappings;
|
||||
|
||||
/// <summary>
|
||||
/// Get or set how reference loops (e.g. a class referencing itself) is handled.
|
||||
@@ -255,7 +257,7 @@ namespace Newtonsoft.Json
|
||||
if (existingValue == null)
|
||||
value = CreateAndPopulateList(reader, objectType);
|
||||
else
|
||||
value = PopulateList(CollectionUtils.CreateListWrapper(existingValue), ReflectionUtils.GetListItemType(objectType), reader);
|
||||
value = PopulateList(CollectionUtils.CreateCollectionWrapper(existingValue), ReflectionUtils.GetCollectionItemType(objectType), reader);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -317,16 +319,13 @@ namespace Newtonsoft.Json
|
||||
|
||||
private MemberMappingCollection GetMemberMappings(Type objectType)
|
||||
{
|
||||
if (_typeMemberMappings == null)
|
||||
_typeMemberMappings = new Dictionary<Type, MemberMappingCollection>();
|
||||
|
||||
MemberMappingCollection memberMappings;
|
||||
|
||||
if (_typeMemberMappings.TryGetValue(objectType, out memberMappings))
|
||||
if (TypeMemberMappings.TryGetValue(objectType, out memberMappings))
|
||||
return memberMappings;
|
||||
|
||||
memberMappings = CreateMemberMappings(objectType);
|
||||
_typeMemberMappings[objectType] = memberMappings;
|
||||
TypeMemberMappings[objectType] = memberMappings;
|
||||
|
||||
return memberMappings;
|
||||
}
|
||||
@@ -388,11 +387,25 @@ namespace Newtonsoft.Json
|
||||
|
||||
private JsonConverter GetConverter(ICustomAttributeProvider attributeProvider, Type targetConvertedType)
|
||||
{
|
||||
JsonConverterAttribute converterAttribute = ReflectionUtils.GetAttribute<JsonConverterAttribute>(attributeProvider, true);
|
||||
Type converterType;
|
||||
|
||||
if (converterAttribute != null)
|
||||
if (!ConverterTypeCache.ContainsKey(attributeProvider))
|
||||
{
|
||||
JsonConverter memberConverter = converterAttribute.CreateJsonConverterInstance();
|
||||
JsonConverterAttribute converterAttribute = ReflectionUtils.GetAttribute<JsonConverterAttribute>(attributeProvider, true);
|
||||
converterType = (converterAttribute != null)
|
||||
? converterAttribute.ConverterType
|
||||
: null;
|
||||
|
||||
ConverterTypeCache[attributeProvider] = converterType;
|
||||
}
|
||||
else
|
||||
{
|
||||
converterType = ConverterTypeCache[attributeProvider];
|
||||
}
|
||||
|
||||
if (converterType != null)
|
||||
{
|
||||
JsonConverter memberConverter = JsonConverterAttribute.CreateJsonConverterInstance(converterType);
|
||||
|
||||
if (!memberConverter.CanConvert(targetConvertedType))
|
||||
throw new JsonSerializationException("JsonConverter {0} on {1} is not compatible with member type {2}.".FormatWith(CultureInfo.InvariantCulture, memberConverter.GetType().Name, attributeProvider, targetConvertedType.Name));
|
||||
@@ -490,7 +503,7 @@ namespace Newtonsoft.Json
|
||||
|
||||
private object CreateAndPopulateList(JsonReader reader, Type objectType)
|
||||
{
|
||||
return CollectionUtils.CreateAndPopulateList(objectType, l => PopulateList(l, ReflectionUtils.GetListItemType(objectType), reader));
|
||||
return CollectionUtils.CreateAndPopulateList(objectType, l => PopulateList(l, ReflectionUtils.GetCollectionItemType(objectType), reader));
|
||||
}
|
||||
|
||||
private IList PopulateList(IList list, Type listItemType, JsonReader reader)
|
||||
|
||||
@@ -116,6 +116,7 @@
|
||||
<Compile Include="NullValueHandling.cs" />
|
||||
<Compile Include="ReferenceLoopHandling.cs" />
|
||||
<Compile Include="Utilities\ConvertUtils.cs" />
|
||||
<Compile Include="Utilities\CollectionWrapper.cs" />
|
||||
<Compile Include="Utilities\DateTimeUtils.cs" />
|
||||
<Compile Include="Utilities\DictionaryWrapper.cs" />
|
||||
<Compile Include="Utilities\JavaScriptUtils.cs" />
|
||||
|
||||
@@ -366,6 +366,33 @@ namespace Newtonsoft.Json.Utilities
|
||||
return false;
|
||||
}
|
||||
|
||||
public static IWrappedCollection CreateCollectionWrapper(object list)
|
||||
{
|
||||
ValidationUtils.ArgumentNotNull(list, "list");
|
||||
|
||||
Type collectionDefinition;
|
||||
if (ReflectionUtils.IsSubClass(list.GetType(), typeof(ICollection<>), out collectionDefinition))
|
||||
{
|
||||
Type collectionItemType = ReflectionUtils.GetCollectionItemType(collectionDefinition);
|
||||
|
||||
// Activator.CreateInstance throws AmbiguousMatchException. Manually invoke constructor
|
||||
Func<Type, IList<object>, object> instanceCreator = (t, a) =>
|
||||
{
|
||||
ConstructorInfo c = t.GetConstructor(new[] { collectionDefinition });
|
||||
return c.Invoke(new[] { list });
|
||||
};
|
||||
|
||||
return (IWrappedCollection)ReflectionUtils.CreateGeneric(typeof(CollectionWrapper<>), new[] { collectionItemType }, instanceCreator, list);
|
||||
}
|
||||
else if (list is IList)
|
||||
{
|
||||
return new CollectionWrapper<object>((IList)list);
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new Exception("Can not create ListWrapper for type {0}.".FormatWith(CultureInfo.InvariantCulture, list.GetType()));
|
||||
}
|
||||
}
|
||||
public static IWrappedList CreateListWrapper(object list)
|
||||
{
|
||||
ValidationUtils.ArgumentNotNull(list, "list");
|
||||
@@ -373,7 +400,7 @@ namespace Newtonsoft.Json.Utilities
|
||||
Type listDefinition;
|
||||
if (ReflectionUtils.IsSubClass(list.GetType(), typeof(IList<>), out listDefinition))
|
||||
{
|
||||
Type listItemType = ReflectionUtils.GetListItemType(listDefinition);
|
||||
Type collectionItemType = ReflectionUtils.GetCollectionItemType(listDefinition);
|
||||
|
||||
// Activator.CreateInstance throws AmbiguousMatchException. Manually invoke constructor
|
||||
Func<Type, IList<object>, object> instanceCreator = (t, a) =>
|
||||
@@ -382,7 +409,7 @@ namespace Newtonsoft.Json.Utilities
|
||||
return c.Invoke(new[] { list });
|
||||
};
|
||||
|
||||
return (IWrappedList)ReflectionUtils.CreateGeneric(typeof(ListWrapper<>), new[] { listItemType }, instanceCreator, list);
|
||||
return (IWrappedList)ReflectionUtils.CreateGeneric(typeof(ListWrapper<>), new[] { collectionItemType }, instanceCreator, list);
|
||||
}
|
||||
else if (list is IList)
|
||||
{
|
||||
@@ -478,7 +505,7 @@ namespace Newtonsoft.Json.Utilities
|
||||
}
|
||||
else if (listType.IsGenericType && listType.GetGenericTypeDefinition() == typeof(IList<>))
|
||||
{
|
||||
list = CollectionUtils.CreateGenericList(ReflectionUtils.GetListItemType(listType));
|
||||
list = CollectionUtils.CreateGenericList(ReflectionUtils.GetCollectionItemType(listType));
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -494,7 +521,7 @@ namespace Newtonsoft.Json.Utilities
|
||||
if (isReadOnlyOrFixedSize)
|
||||
{
|
||||
if (listType.IsArray)
|
||||
list = ToArray(((List<object>)list).ToArray(), ReflectionUtils.GetListItemType(listType));
|
||||
list = ToArray(((List<object>)list).ToArray(), ReflectionUtils.GetCollectionItemType(listType));
|
||||
else if (ReflectionUtils.IsSubClass(listType, typeof(ReadOnlyCollection<>)))
|
||||
list = (IList)Activator.CreateInstance(listType, list);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,268 @@
|
||||
#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
|
||||
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading;
|
||||
using Newtonsoft.Json.Utilities;
|
||||
using System.Linq;
|
||||
using System.Globalization;
|
||||
|
||||
namespace Newtonsoft.Json.Utilities
|
||||
{
|
||||
internal interface IWrappedCollection : IList
|
||||
{
|
||||
object UnderlyingCollection { get; }
|
||||
}
|
||||
|
||||
internal class CollectionWrapper<T> : ICollection<T>, IWrappedCollection
|
||||
{
|
||||
private readonly IList _list;
|
||||
private readonly ICollection<T> _genericCollection;
|
||||
private object _syncRoot;
|
||||
|
||||
public CollectionWrapper(IList list)
|
||||
{
|
||||
ValidationUtils.ArgumentNotNull(list, "list");
|
||||
|
||||
_list = list;
|
||||
}
|
||||
|
||||
public CollectionWrapper(ICollection<T> list)
|
||||
{
|
||||
ValidationUtils.ArgumentNotNull(list, "list");
|
||||
|
||||
_genericCollection = list;
|
||||
}
|
||||
|
||||
public void Add(T item)
|
||||
{
|
||||
if (_genericCollection != null)
|
||||
_genericCollection.Add(item);
|
||||
else
|
||||
_list.Add(item);
|
||||
}
|
||||
|
||||
public void Clear()
|
||||
{
|
||||
if (_genericCollection != null)
|
||||
_genericCollection.Clear();
|
||||
else
|
||||
_list.Clear();
|
||||
}
|
||||
|
||||
public bool Contains(T item)
|
||||
{
|
||||
if (_genericCollection != null)
|
||||
return _genericCollection.Contains(item);
|
||||
else
|
||||
return _list.Contains(item);
|
||||
}
|
||||
|
||||
public void CopyTo(T[] array, int arrayIndex)
|
||||
{
|
||||
if (_genericCollection != null)
|
||||
_genericCollection.CopyTo(array, arrayIndex);
|
||||
else
|
||||
_list.CopyTo(array, arrayIndex);
|
||||
}
|
||||
|
||||
public int Count
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_genericCollection != null)
|
||||
return _genericCollection.Count;
|
||||
else
|
||||
return _list.Count;
|
||||
}
|
||||
}
|
||||
|
||||
public bool IsReadOnly
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_genericCollection != null)
|
||||
return _genericCollection.IsReadOnly;
|
||||
else
|
||||
return _list.IsReadOnly;
|
||||
}
|
||||
}
|
||||
|
||||
public bool Remove(T item)
|
||||
{
|
||||
if (_genericCollection != null)
|
||||
{
|
||||
return _genericCollection.Remove(item);
|
||||
}
|
||||
else
|
||||
{
|
||||
bool contains = _list.Contains(item);
|
||||
|
||||
if (contains)
|
||||
_list.Remove(item);
|
||||
|
||||
return contains;
|
||||
}
|
||||
}
|
||||
|
||||
public IEnumerator<T> GetEnumerator()
|
||||
{
|
||||
if (_genericCollection != null)
|
||||
return _genericCollection.GetEnumerator();
|
||||
|
||||
return _list.Cast<T>().GetEnumerator();
|
||||
}
|
||||
|
||||
IEnumerator IEnumerable.GetEnumerator()
|
||||
{
|
||||
if (_genericCollection != null)
|
||||
return _genericCollection.GetEnumerator();
|
||||
else
|
||||
return _list.GetEnumerator();
|
||||
}
|
||||
|
||||
int IList.Add(object value)
|
||||
{
|
||||
VerifyValueType(value);
|
||||
Add((T)value);
|
||||
|
||||
return (Count - 1);
|
||||
}
|
||||
|
||||
bool IList.Contains(object value)
|
||||
{
|
||||
if (IsCompatibleObject(value))
|
||||
return Contains((T)value);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
int IList.IndexOf(object value)
|
||||
{
|
||||
if (_genericCollection != null)
|
||||
throw new Exception("Wrapped ICollection<T> does not support IndexOf.");
|
||||
|
||||
if (IsCompatibleObject(value))
|
||||
return _list.IndexOf((T)value);
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
void IList.RemoveAt(int index)
|
||||
{
|
||||
if (_genericCollection != null)
|
||||
throw new Exception("Wrapped ICollection<T> does not support RemoveAt.");
|
||||
|
||||
_list.RemoveAt(index);
|
||||
}
|
||||
|
||||
void IList.Insert(int index, object value)
|
||||
{
|
||||
if (_genericCollection != null)
|
||||
throw new Exception("Wrapped ICollection<T> does not support Insert.");
|
||||
|
||||
VerifyValueType(value);
|
||||
_list.Insert(index, (T)value);
|
||||
}
|
||||
|
||||
bool IList.IsFixedSize
|
||||
{
|
||||
get { return false; }
|
||||
}
|
||||
|
||||
void IList.Remove(object value)
|
||||
{
|
||||
if (IsCompatibleObject(value))
|
||||
Remove((T)value);
|
||||
}
|
||||
|
||||
object IList.this[int index]
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_genericCollection != null)
|
||||
throw new Exception("Wrapped ICollection<T> does not support indexer.");
|
||||
|
||||
return _list[index];
|
||||
}
|
||||
set
|
||||
{
|
||||
if (_genericCollection != null)
|
||||
throw new Exception("Wrapped ICollection<T> does not support indexer.");
|
||||
|
||||
VerifyValueType(value);
|
||||
_list[index] = (T)value;
|
||||
}
|
||||
}
|
||||
|
||||
void ICollection.CopyTo(Array array, int arrayIndex)
|
||||
{
|
||||
CopyTo((T[])array, arrayIndex);
|
||||
}
|
||||
|
||||
bool ICollection.IsSynchronized
|
||||
{
|
||||
get { return false; }
|
||||
}
|
||||
|
||||
object ICollection.SyncRoot
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_syncRoot == null)
|
||||
Interlocked.CompareExchange(ref _syncRoot, new object(), null);
|
||||
|
||||
return _syncRoot;
|
||||
}
|
||||
}
|
||||
|
||||
private static void VerifyValueType(object value)
|
||||
{
|
||||
if (!IsCompatibleObject(value))
|
||||
throw new ArgumentException("The value '{0}' is not of type '{1}' and cannot be used in this generic collection.".FormatWith(CultureInfo.InvariantCulture, value, typeof(T)), "value");
|
||||
}
|
||||
|
||||
private static bool IsCompatibleObject(object value)
|
||||
{
|
||||
if (!(value is T) && (value != null || typeof(T).IsValueType))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public object UnderlyingCollection
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_genericCollection != null)
|
||||
return _genericCollection;
|
||||
else
|
||||
return _list;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -181,11 +181,11 @@ namespace Newtonsoft.Json.Utilities
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the type of the typed list's items.
|
||||
/// Gets the type of the typed collection's items.
|
||||
/// </summary>
|
||||
/// <param name="type">The type.</param>
|
||||
/// <returns>The type of the typed list's items.</returns>
|
||||
public static Type GetListItemType(Type type)
|
||||
/// <returns>The type of the typed collection's items.</returns>
|
||||
public static Type GetCollectionItemType(Type type)
|
||||
{
|
||||
ValidationUtils.ArgumentNotNull(type, "type");
|
||||
Type genericListType;
|
||||
@@ -194,10 +194,10 @@ namespace Newtonsoft.Json.Utilities
|
||||
{
|
||||
return type.GetElementType();
|
||||
}
|
||||
else if (IsSubClass(type, typeof(IList<>), out genericListType))
|
||||
else if (IsSubClass(type, typeof(ICollection<>), out genericListType))
|
||||
{
|
||||
if (genericListType.IsGenericTypeDefinition)
|
||||
throw new Exception("Type {0} is not a list.".FormatWith(CultureInfo.InvariantCulture, type));
|
||||
throw new Exception("Type {0} is not a collection.".FormatWith(CultureInfo.InvariantCulture, type));
|
||||
|
||||
return genericListType.GetGenericArguments()[0];
|
||||
}
|
||||
@@ -207,7 +207,7 @@ namespace Newtonsoft.Json.Utilities
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new Exception("Type {0} is not a list.".FormatWith(CultureInfo.InvariantCulture, type));
|
||||
throw new Exception("Type {0} is not a collection.".FormatWith(CultureInfo.InvariantCulture, type));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -266,7 +266,7 @@ namespace Newtonsoft.Json.Utilities
|
||||
{
|
||||
ValidationUtils.ArgumentNotNull(list, "list");
|
||||
|
||||
Type elementType = GetListItemType(list.GetType());
|
||||
Type elementType = GetCollectionItemType(list.GetType());
|
||||
|
||||
if (elementType.IsValueType)
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user