Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/mono/Newtonsoft.Json.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/Src
diff options
context:
space:
mode:
Diffstat (limited to 'Src')
-rw-r--r--Src/Doc/SerializationErrorHandling.html172
-rw-r--r--Src/Doc/SerializingJSON.html7
-rw-r--r--Src/Doc/doc.shfb2
-rw-r--r--Src/Doc/doc.sitemap1
-rw-r--r--Src/Newtonsoft.Json.Tests/Newtonsoft.Json.Tests.Compact.csproj1
-rw-r--r--Src/Newtonsoft.Json.Tests/Newtonsoft.Json.Tests.Net20.csproj1
-rw-r--r--Src/Newtonsoft.Json.Tests/Newtonsoft.Json.Tests.Silverlight.csproj1
-rw-r--r--Src/Newtonsoft.Json.Tests/Newtonsoft.Json.Tests.csproj1
-rw-r--r--Src/Newtonsoft.Json.Tests/Serialization/SerializationErrorHandlingTests.cs133
-rw-r--r--Src/Newtonsoft.Json.Tests/TestObjects/PersonError.cs35
-rw-r--r--Src/Newtonsoft.Json.sln2
-rw-r--r--Src/Newtonsoft.Json/JsonSerializer.cs16
-rw-r--r--Src/Newtonsoft.Json/JsonSerializerSettings.cs6
-rw-r--r--Src/Newtonsoft.Json/Linq/ComponentModel/JPropertyDescriptor.cs17
-rw-r--r--Src/Newtonsoft.Json/Linq/JContainer.cs4
-rw-r--r--Src/Newtonsoft.Json/Linq/JObject.cs4
-rw-r--r--Src/Newtonsoft.Json/Newtonsoft.Json.Compact.csproj1
-rw-r--r--Src/Newtonsoft.Json/Newtonsoft.Json.Net20.csproj1
-rw-r--r--Src/Newtonsoft.Json/Newtonsoft.Json.Silverlight.csproj1
-rw-r--r--Src/Newtonsoft.Json/Newtonsoft.Json.csproj1
-rw-r--r--Src/Newtonsoft.Json/Serialization/ErrorEventArgs.cs35
-rw-r--r--Src/Newtonsoft.Json/Serialization/JsonSerializerInternalBase.cs24
-rw-r--r--Src/Newtonsoft.Json/Serialization/JsonSerializerInternalReader.cs59
-rw-r--r--Src/Newtonsoft.Json/Serialization/JsonSerializerInternalWriter.cs69
-rw-r--r--Src/Newtonsoft.Json/Serialization/JsonSerializerProxy.cs10
25 files changed, 516 insertions, 88 deletions
diff --git a/Src/Doc/SerializationErrorHandling.html b/Src/Doc/SerializationErrorHandling.html
new file mode 100644
index 0000000..9ec8acb
--- /dev/null
+++ b/Src/Doc/SerializationErrorHandling.html
@@ -0,0 +1,172 @@
+<html>
+
+ <head>
+ <title>Serialization Error Handling</title>
+ <link href="styles.css" rel="stylesheet" type="text/css" />
+ <link href="custom.css" rel="stylesheet" type="text/css" />
+ </head>
+
+ <body>
+
+ <div id="control">
+ <span class="productTitle">Json.NET - Quick Starts & API Documentation</span><br />
+ <span class="topicTitle">Serialization Error Handling</span></div>
+
+ <div id="content">
+ <span style="color: DarkGray"> </span>
+
+ <p>Json.NET supports error handling during serialization and deserialization. Error handling lets
+ you catch an error and choose whether to handle it and continue with serialization or let the error
+ bubble up and be thrown in your application.</p>
+ <p>Error handling is defined through two methods:
+ the Error event on JsonSerializer and the OnErrorAttribute.</p>
+ <h3>Error Event</h3>
+
+ <p>
+ The <a href="./html/E_Newtonsoft_Json_JsonSerializer_Error.htm">Error</a> event is an event handler found on <a href="./html/T_Newtonsoft_Json_JsonSerializer.htm">JsonSerializer</a>. The error event is raised whenever an
+ exception is thrown while serializing or deserialing JSON. Like all settings found on JsonSerializer
+ it can also be set on <a href="./html/T_Newtonsoft_Json_JsonSerializer.htm">JsonSerializerSettings</a> and passed to the serialization methods on JsonConvert.</p>
+
+ <div class="overflowpanel"> <div class="code">
+<div style="font-family: Courier New; font-size: 10pt; color: black;">
+<pre style="margin: 0px;"><span style="color: #2b91af;">List</span>&lt;<span style="color: blue;">string</span>&gt; errors = <span style="color: blue;">new</span> <span style="color: #2b91af;">List</span>&lt;<span style="color: blue;">string</span>&gt;();</pre>
+<pre style="margin: 0px;">&nbsp;</pre>
+<pre style="margin: 0px;"><span style="color: #2b91af;">List</span>&lt;<span style="color: #2b91af;">DateTime</span>&gt; c = <span style="color: #2b91af;">JsonConvert</span>.DeserializeObject&lt;<span style="color: #2b91af;">List</span>&lt;<span style="color: #2b91af;">DateTime</span>&gt;&gt;(<span style="color: #a31515;">@"[</span></pre>
+<pre style="margin: 0px;"><span style="color: #a31515;">&nbsp; ""2009-09-09T00:00:00Z"",</span></pre>
+<pre style="margin: 0px;"><span style="color: #a31515;">&nbsp; ""I am not a date and will error!"",</span></pre>
+<pre style="margin: 0px;"><span style="color: #a31515;">&nbsp; [</span></pre>
+<pre style="margin: 0px;"><span style="color: #a31515;">&nbsp; &nbsp; 1</span></pre>
+<pre style="margin: 0px;"><span style="color: #a31515;">&nbsp; ],</span></pre>
+<pre style="margin: 0px;"><span style="color: #a31515;">&nbsp; ""1977-02-20T00:00:00Z"",</span></pre>
+<pre style="margin: 0px;"><span style="color: #a31515;">&nbsp; null,</span></pre>
+<pre style="margin: 0px;"><span style="color: #a31515;">&nbsp; ""2000-12-01T00:00:00Z""</span></pre>
+<pre style="margin: 0px;"><span style="color: #a31515;">]"</span>,</pre>
+<pre style="margin: 0px;">&nbsp; <span style="color: blue;">new</span> <span style="color: #2b91af;">JsonSerializerSettings</span></pre>
+<pre style="margin: 0px;">&nbsp; &nbsp; {</pre>
+<pre style="margin: 0px;">&nbsp; &nbsp; &nbsp; Error = <span style="color: blue;">delegate</span>(<span style="color: blue;">object</span> sender, <span style="color: #2b91af;">ErrorEventArgs</span> args)</pre>
+<pre style="margin: 0px;">&nbsp; &nbsp; &nbsp; &nbsp; {</pre>
+<pre style="margin: 0px;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; errors.Add(args.ErrorContext.Error.Message);</pre>
+<pre style="margin: 0px;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; args.ErrorContext.Handled = <span style="color: blue;">true</span>;</pre>
+<pre style="margin: 0px;">&nbsp; &nbsp; &nbsp; &nbsp; },</pre>
+<pre style="margin: 0px;">&nbsp; &nbsp; &nbsp; Converters = { <span style="color: blue;">new</span> <span style="color: #2b91af;">IsoDateTimeConverter</span>() }</pre>
+<pre style="margin: 0px;">&nbsp; &nbsp; });</pre>
+<pre style="margin: 0px;">&nbsp;</pre>
+<pre style="margin: 0px;"><span style="color: green;">// 2009-09-09T00:00:00Z</span></pre>
+<pre style="margin: 0px;"><span style="color: green;">// 1977-02-20T00:00:00Z</span></pre>
+<pre style="margin: 0px;"><span style="color: green;">// 2000-12-01T00:00:00Z</span></pre>
+<pre style="margin: 0px;">&nbsp;</pre>
+<pre style="margin: 0px;"><span style="color: green;">// The string was not recognized as a valid DateTime. There is a unknown word starting at index 0.</span></pre>
+<pre style="margin: 0px;"><span style="color: green;">// Unexpected token parsing date. Expected String, got StartArray.</span></pre>
+<pre style="margin: 0px;"><span style="color: green;">// Cannot convert null value to System.DateTime.</span></pre>
+</div>
+</div>
+</div>
+<p>
+ In this example we are deserializing a JSON array to a collection of DateTimes. On the JsonSerializerSettings
+ a handler has been assigned to the Error event which will log the error message and mark the error as handled.
+</p>
+<p>
+ The result of deserializing the JSON is three successfully deserialized dates and three error messages:
+ one for the badly formatted string, "I am not a date and will error!", one for the nested JSON array and one
+ for the null value since the list doesn't allow nullable DateTimes. The event handler has logged these messages
+ and Json.NET has continued on deserializing the JSON because the errors were marked as handled.
+</p>
+<p>
+ One thing to note with error handling in Json.NET is that an unhandled error will bubble up and raise the event
+ on each of its parents, e.g. an unhandled error when serializing a collection of objects will be raised twice,
+ once against the object and then again on the collection. This will let you handle an error either where it
+ occurred or on one of its parents.
+</p>
+
+
+<div class="overflowpanel"> <div class="code">
+<div style="font-family: Courier New; font-size: 10pt; color: black;">
+<pre style="margin: 0px;"><span style="color: #2b91af;">JsonSerializer</span> serializer = <span style="color: blue;">new</span> <span style="color: #2b91af;">JsonSerializer</span>();</pre>
+<pre style="margin: 0px;">serializer.Error += <span style="color: blue;">delegate</span>(<span style="color: blue;">object</span> sender, <span style="color: #2b91af;">ErrorEventArgs</span> args)</pre>
+<pre style="margin: 0px;">&nbsp; {</pre>
+<pre style="margin: 0px;">&nbsp; &nbsp; <span style="color: green;">// only log an error once</span></pre>
+<pre style="margin: 0px;">&nbsp; &nbsp; <span style="color: blue;">if</span> (args.CurrentObject == args.ErrorContext.OriginalObject)</pre>
+<pre style="margin: 0px;">&nbsp; &nbsp; &nbsp; errors.Add(args.ErrorContext.Error.Message);</pre>
+<pre style="margin: 0px;">&nbsp; };</pre>
+</div>
+</div></div>
+
+<p>If you aren't immediately handling an error and only want to perform an action against it once then
+you can check to see whether the <a href="./html/T_Newtonsoft_Json_Serialization_ErrorEventArgs.htm">ErrorEventArg</a>'s CurrentObject is equal to the OriginalObject.
+OriginalObject is the object that threw the error and CurrentObject is the object that the event is being raised
+against. They will only equal the first time the event is raised against the OriginalObject.</p>
+
+ <h3>OnErrorAttribute</h3>
+
+ <p>
+ The <a href="./html/T_Newtonsoft_Json_Serialization_OnErrorAttribute.htm">OnErrorAttribute</a> works much like the other <a href="SerializationCallbacks.html">.NET serialization attributes</a> that Json.NET supports.
+ To use it you simply place the attribute on a method which takes the correct parameters: a StreamingContext and a ErrorContext.
+ The name of the method doesn't matter. </p>
+ <div class="overflowpanel"> <div class="code">
+
+ <div style="font-family: Courier New; font-size: 10pt; color: black;">
+<pre style="margin: 0px;"><span style="color: blue;">public</span> <span style="color: blue;">class</span> <span style="color: #2b91af;">PersonError</span></pre>
+<pre style="margin: 0px;">{</pre>
+<pre style="margin: 0px;">&nbsp; <span style="color: blue;">private</span> <span style="color: #2b91af;">List</span>&lt;<span style="color: blue;">string</span>&gt; _roles;</pre>
+<pre style="margin: 0px;">&nbsp;</pre>
+<pre style="margin: 0px;">&nbsp; <span style="color: blue;">public</span> <span style="color: blue;">string</span> Name { <span style="color: blue;">get</span>; <span style="color: blue;">set</span>; }</pre>
+<pre style="margin: 0px;">&nbsp; <span style="color: blue;">public</span> <span style="color: blue;">int</span> Age { <span style="color: blue;">get</span>; <span style="color: blue;">set</span>; }</pre>
+<pre style="margin: 0px;">&nbsp; <span style="color: blue;">public</span> <span style="color: #2b91af;">List</span>&lt;<span style="color: blue;">string</span>&gt; Roles</pre>
+<pre style="margin: 0px;">&nbsp; {</pre>
+<pre style="margin: 0px;">&nbsp; &nbsp; <span style="color: blue;">get</span></pre>
+<pre style="margin: 0px;">&nbsp; &nbsp; {</pre>
+<pre style="margin: 0px;">&nbsp; &nbsp; &nbsp; <span style="color: blue;">if</span> (_roles == <span style="color: blue;">null</span>)</pre>
+<pre style="margin: 0px;">&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: blue;">throw</span> <span style="color: blue;">new</span> <span style="color: #2b91af;">Exception</span>(<span style="color: #a31515;">"Roles not loaded!"</span>);</pre>
+<pre style="margin: 0px;">&nbsp;</pre>
+<pre style="margin: 0px;">&nbsp; &nbsp; &nbsp; <span style="color: blue;">return</span> _roles;</pre>
+<pre style="margin: 0px;">&nbsp; &nbsp; }</pre>
+<pre style="margin: 0px;">&nbsp; &nbsp; <span style="color: blue;">set</span> { _roles = <span style="color: blue;">value</span>; }</pre>
+<pre style="margin: 0px;">&nbsp; }</pre>
+<pre style="margin: 0px;">&nbsp; <span style="color: blue;">public</span> <span style="color: blue;">string</span> Title { <span style="color: blue;">get</span>; <span style="color: blue;">set</span>; }</pre>
+<pre style="margin: 0px;">&nbsp;</pre>
+<pre style="margin: 0px;">&nbsp; [<span style="color: #2b91af;">OnError</span>]</pre>
+<pre style="margin: 0px;">&nbsp; <span style="color: blue;">internal</span> <span style="color: blue;">void</span> OnError(<span style="color: #2b91af;">StreamingContext</span> context, <span style="color: #2b91af;">ErrorContext</span> errorContext)</pre>
+<pre style="margin: 0px;">&nbsp; {</pre>
+<pre style="margin: 0px;">&nbsp; &nbsp; errorContext.Handled = <span style="color: blue;">true</span>;</pre>
+<pre style="margin: 0px;">&nbsp; }</pre>
+<pre style="margin: 0px;">}</pre>
+</div>
+</div></div>
+ <p>
+ In this example accessing the the Roles property will throw an exception when no roles have
+ been set. The HandleError method will set the error when serializing Roles as handled and allow Json.NET to continue
+ serializing the class.
+ </p>
+
+ <div class="overflowpanel"> <div class="code">
+<div style="font-family: Courier New; font-size: 10pt; color: black;">
+<pre style="margin: 0px;"><span style="color: #2b91af;">PersonError</span> person = <span style="color: blue;">new</span> <span style="color: #2b91af;">PersonError</span></pre>
+<pre style="margin: 0px;">&nbsp; {</pre>
+<pre style="margin: 0px;">&nbsp; &nbsp; Name = <span style="color: #a31515;">"George Michael Bluth"</span>,</pre>
+<pre style="margin: 0px;">&nbsp; &nbsp; Age = 16,</pre>
+<pre style="margin: 0px;">&nbsp; &nbsp; Roles = <span style="color: blue;">null</span>,</pre>
+<pre style="margin: 0px;">&nbsp; &nbsp; Title = <span style="color: #a31515;">"Mister Manager"</span></pre>
+<pre style="margin: 0px;">&nbsp; };</pre>
+<pre style="margin: 0px;">&nbsp;</pre>
+<pre style="margin: 0px;"><span style="color: blue;">string</span> json = <span style="color: #2b91af;">JsonConvert</span>.SerializeObject(person, <span style="color: #2b91af;">Formatting</span>.Indented);</pre>
+<pre style="margin: 0px;">&nbsp;</pre>
+<pre style="margin: 0px;"><span style="color: #2b91af;">Console</span>.WriteLine(json);</pre>
+<pre style="margin: 0px;"><span style="color: green;">//{</span></pre>
+<pre style="margin: 0px;"><span style="color: green;">//&nbsp; "Name": "George Michael Bluth",</span></pre>
+<pre style="margin: 0px;"><span style="color: green;">//&nbsp; "Age": 16,</span></pre>
+<pre style="margin: 0px;"><span style="color: green;">//&nbsp; "Title": "Mister Manager"</span></pre>
+<pre style="margin: 0px;"><span style="color: green;">//}</span></pre>
+</div>
+</div></div>
+
+
+ <div id="footer">
+
+
+
+ </div>
+ </div>
+
+ </body>
+
+</html> \ No newline at end of file
diff --git a/Src/Doc/SerializingJSON.html b/Src/Doc/SerializingJSON.html
index 807eaf5..3842eb9 100644
--- a/Src/Doc/SerializingJSON.html
+++ b/Src/Doc/SerializingJSON.html
@@ -92,12 +92,13 @@
the member's DefaultValueAttribute. Include or ignore.</p>
<h5>ObjectCreationHandling</h5>
<p>Controls how objects are created during deserialization. Auto, reuse, replace.</p>
+ <h5>TypeNameHandling</h5>
+<p>Controls whether .NET type names are included in serialized JSON and read during deserialization when creating objects. None, Objects, Arrays or All.</p>
+ <h5>ConstructorHandling</h5>
+<p>Controls how constructors are used when initializing objects during deserialization. Default or AllowNonPublicDefaultConstructor.</p>
<h5>Converters</h5>
<p>A collection of JsonConverters that will be used during serialization and
deserialization.</p>
- <h5>TypeNameHandling</h5>
-<p>Controls how .NET type names are used when serializing and deserializing JSON. If
- type names are SDFSDFSDF</p>
<h3>JsonConverters</h3>
diff --git a/Src/Doc/doc.shfb b/Src/Doc/doc.shfb
index 543b5e5..c0f4372 100644
--- a/Src/Doc/doc.shfb
+++ b/Src/Doc/doc.shfb
@@ -7,6 +7,7 @@
<namespaceSummaryItem name="Newtonsoft.Json" isDocumented="True">The &lt;b&gt;Newtonsoft.Json&lt;/b&gt; namespace provides classes that are used to implement the core services of the framework.</namespaceSummaryItem>
<namespaceSummaryItem name="Newtonsoft.Json.Converters" isDocumented="True">The &lt;b&gt;Newtonsoft.Json.Converters&lt;/b&gt; namespace provides classes that inherit from &lt;a href="T_Newtonsoft_Json_JsonConverter.htm"&gt;JsonConverter&lt;/a&gt;.</namespaceSummaryItem>
<namespaceSummaryItem name="Newtonsoft.Json.Linq" isDocumented="True">The &lt;b&gt;Newtonsoft.Json.Linq&lt;/b&gt; namespace provides classes that are used to implement LINQ to JSON.</namespaceSummaryItem>
+ <namespaceSummaryItem name="Newtonsoft.Json.Linq.ComponentModel" isDocumented="True">The &lt;b&gt;Newtonsoft.Json.Linq.ComponentModel&lt;/b&gt; namespace provides classes for LINQ to JSON databinding.</namespaceSummaryItem>
<namespaceSummaryItem name="Newtonsoft.Json.Schema" isDocumented="True">The &lt;b&gt;Newtonsoft.Json.Schema&lt;/b&gt; namespace provides classes that are used to implement JSON schema.</namespaceSummaryItem>
<namespaceSummaryItem name="Newtonsoft.Json.Serialization" isDocumented="True">The &lt;b&gt;Newtonsoft.Json.Linq&lt;/b&gt; namespace provides classes that are used when serializing and deserializing JSON.</namespaceSummaryItem>
<namespaceSummaryItem name="Newtonsoft.Json.Utilities" isDocumented="False" />
@@ -25,6 +26,7 @@
<contentItem sourcePath=".\SerializationCallbacks.html" destPath="" excludeItems="False" />
<contentItem sourcePath=".\SerializationAttributes.html" destPath="" excludeItems="False" />
<contentItem sourcePath=".\SerializingCollections.html" destPath="" excludeItems="False" />
+ <contentItem sourcePath=".\SerializationErrorHandling.html" destPath="" excludeItems="False" />
</additionalContent>
<ProjectSummary />
<MissingTags>Summary, Parameter, Returns, AutoDocumentCtors, Namespace, TypeParameter</MissingTags>
diff --git a/Src/Doc/doc.sitemap b/Src/Doc/doc.sitemap
index f00d764..ea3b290 100644
--- a/Src/Doc/doc.sitemap
+++ b/Src/Doc/doc.sitemap
@@ -6,6 +6,7 @@
<siteMapNode title="Serializing Dates in JSON" url=".\DatesInJSON.html" />
<siteMapNode title="Serializing Collections" url=".\SerializingCollections.html" />
<siteMapNode title="Serialization Callbacks" url=".\SerializationCallbacks.html" />
+ <siteMapNode title="Serialization Error Handling" url=".\SerializationErrorHandling.html" />
<siteMapNode title="Serialization and Preserving Object References" url=".\PreserveObjectReferences.html" />
<siteMapNode title="CustomCreationConverter" url=".\CustomCreationConverter.html" />
<siteMapNode title="Contract Resolvers" url=".\ContractResolver.html" />
diff --git a/Src/Newtonsoft.Json.Tests/Newtonsoft.Json.Tests.Compact.csproj b/Src/Newtonsoft.Json.Tests/Newtonsoft.Json.Tests.Compact.csproj
index 5ed093f..84fa77b 100644
--- a/Src/Newtonsoft.Json.Tests/Newtonsoft.Json.Tests.Compact.csproj
+++ b/Src/Newtonsoft.Json.Tests/Newtonsoft.Json.Tests.Compact.csproj
@@ -120,6 +120,7 @@
<Compile Include="TestObjects\NonRequest.cs" />
<Compile Include="TestObjects\NullableDateTimeTestClass.cs" />
<Compile Include="TestObjects\ObjectArrayPropertyTest.cs" />
+ <Compile Include="TestObjects\PersonError.cs" />
<Compile Include="TestObjects\PersonRaw.cs" />
<Compile Include="TestObjects\PhoneNumber.cs" />
<Compile Include="TestObjects\PrivateConstructorTestClass.cs" />
diff --git a/Src/Newtonsoft.Json.Tests/Newtonsoft.Json.Tests.Net20.csproj b/Src/Newtonsoft.Json.Tests/Newtonsoft.Json.Tests.Net20.csproj
index fc9537b..00e59e6 100644
--- a/Src/Newtonsoft.Json.Tests/Newtonsoft.Json.Tests.Net20.csproj
+++ b/Src/Newtonsoft.Json.Tests/Newtonsoft.Json.Tests.Net20.csproj
@@ -87,6 +87,7 @@
<Compile Include="TestObjects\NonRequest.cs" />
<Compile Include="TestObjects\ObjectArrayPropertyTest.cs" />
<Compile Include="Serialization\PopulateTests.cs" />
+ <Compile Include="TestObjects\PersonError.cs" />
<Compile Include="TestObjects\PrivateConstructorTestClass.cs" />
<Compile Include="TestObjects\PrivateConstructorWithPublicParametizedConstructorTestClass.cs" />
<Compile Include="TestObjects\PropertyCase.cs" />
diff --git a/Src/Newtonsoft.Json.Tests/Newtonsoft.Json.Tests.Silverlight.csproj b/Src/Newtonsoft.Json.Tests/Newtonsoft.Json.Tests.Silverlight.csproj
index 2f18bb4..3f39a17 100644
--- a/Src/Newtonsoft.Json.Tests/Newtonsoft.Json.Tests.Silverlight.csproj
+++ b/Src/Newtonsoft.Json.Tests/Newtonsoft.Json.Tests.Silverlight.csproj
@@ -126,6 +126,7 @@
<Compile Include="TestObjects\NonRequest.cs" />
<Compile Include="TestObjects\NullableDateTimeTestClass.cs" />
<Compile Include="TestObjects\ObjectArrayPropertyTest.cs" />
+ <Compile Include="TestObjects\PersonError.cs" />
<Compile Include="TestObjects\PersonRaw.cs" />
<Compile Include="TestObjects\PhoneNumber.cs" />
<Compile Include="TestObjects\PrivateConstructorTestClass.cs" />
diff --git a/Src/Newtonsoft.Json.Tests/Newtonsoft.Json.Tests.csproj b/Src/Newtonsoft.Json.Tests/Newtonsoft.Json.Tests.csproj
index a5de0ba..14f0016 100644
--- a/Src/Newtonsoft.Json.Tests/Newtonsoft.Json.Tests.csproj
+++ b/Src/Newtonsoft.Json.Tests/Newtonsoft.Json.Tests.csproj
@@ -110,6 +110,7 @@
<Compile Include="Linq\ComponentModel\JTypeDescriptionProviderTests.cs" />
<Compile Include="Linq\ComponentModel\JTypeDescriptorTests.cs" />
<Compile Include="Serialization\ConstructorHandlingTests.cs" />
+ <Compile Include="TestObjects\PersonError.cs" />
<Compile Include="TestObjects\PrivateConstructorTestClass.cs" />
<Compile Include="TestObjects\PrivateConstructorWithPublicParametizedConstructorTestClass.cs" />
<Compile Include="TestObjects\Content.cs" />
diff --git a/Src/Newtonsoft.Json.Tests/Serialization/SerializationErrorHandlingTests.cs b/Src/Newtonsoft.Json.Tests/Serialization/SerializationErrorHandlingTests.cs
index d36233f..2cd9f01 100644
--- a/Src/Newtonsoft.Json.Tests/Serialization/SerializationErrorHandlingTests.cs
+++ b/Src/Newtonsoft.Json.Tests/Serialization/SerializationErrorHandlingTests.cs
@@ -30,6 +30,9 @@ using System.Text;
using Newtonsoft.Json.Converters;
using Newtonsoft.Json.Tests.TestObjects;
using NUnit.Framework;
+using Newtonsoft.Json.Serialization;
+using System.IO;
+using ErrorEventArgs=Newtonsoft.Json.Serialization.ErrorEventArgs;
namespace Newtonsoft.Json.Tests.Serialization
{
@@ -201,5 +204,135 @@ namespace Newtonsoft.Json.Tests.Serialization
Assert.AreEqual(new DateTime(1977, 2, 20, 0, 0, 0, DateTimeKind.Utc), c[1]);
Assert.AreEqual(new DateTime(2000, 12, 1, 0, 0, 0, DateTimeKind.Utc), c[2]);
}
+
+ [Test]
+ public void DeserializingErrorHandlingUsingEvent()
+ {
+ List<string> errors = new List<string>();
+
+ List<DateTime> c = JsonConvert.DeserializeObject<List<DateTime>>(@"[
+ ""2009-09-09T00:00:00Z"",
+ ""I am not a date and will error!"",
+ [
+ 1
+ ],
+ ""1977-02-20T00:00:00Z"",
+ null,
+ ""2000-12-01T00:00:00Z""
+ ]",
+ new JsonSerializerSettings
+ {
+ Error = delegate(object sender, ErrorEventArgs args)
+ {
+ errors.Add(args.ErrorContext.Error.Message);
+ args.ErrorContext.Handled = true;
+ },
+ Converters = { new IsoDateTimeConverter() }
+ });
+
+ // 2009-09-09T00:00:00Z
+ // 1977-02-20T00:00:00Z
+ // 2000-12-01T00:00:00Z
+
+ // The string was not recognized as a valid DateTime. There is a unknown word starting at index 0.
+ // Unexpected token parsing date. Expected String, got StartArray.
+ // Cannot convert null value to System.DateTime.
+
+ Assert.AreEqual(3, c.Count);
+ Assert.AreEqual(new DateTime(2009, 9, 9, 0, 0, 0, DateTimeKind.Utc), c[0]);
+ Assert.AreEqual(new DateTime(1977, 2, 20, 0, 0, 0, DateTimeKind.Utc), c[1]);
+ Assert.AreEqual(new DateTime(2000, 12, 1, 0, 0, 0, DateTimeKind.Utc), c[2]);
+
+ Assert.AreEqual(3, errors.Count);
+ Assert.AreEqual("The string was not recognized as a valid DateTime. There is a unknown word starting at index 0.", errors[0]);
+ Assert.AreEqual("Unexpected token parsing date. Expected String, got StartArray.", errors[1]);
+ Assert.AreEqual("Cannot convert null value to System.DateTime.", errors[2]);
+ }
+
+ [Test]
+ public void DeserializingErrorInDateTimeCollectionWithAttributeWithEventNotCalled()
+ {
+ bool eventErrorHandlerCalled = false;
+
+ DateTimeErrorObjectCollection c = JsonConvert.DeserializeObject<DateTimeErrorObjectCollection>(@"[
+ ""2009-09-09T00:00:00Z"",
+ ""kjhkjhkjhkjh"",
+ [
+ 1
+ ],
+ ""1977-02-20T00:00:00Z"",
+ null,
+ ""2000-12-01T00:00:00Z""
+]",
+ new JsonSerializerSettings
+ {
+ Error = (s, a) => eventErrorHandlerCalled = true,
+ Converters =
+ {
+ new IsoDateTimeConverter()
+ }
+ });
+
+ Assert.AreEqual(3, c.Count);
+ Assert.AreEqual(new DateTime(2009, 9, 9, 0, 0, 0, DateTimeKind.Utc), c[0]);
+ Assert.AreEqual(new DateTime(1977, 2, 20, 0, 0, 0, DateTimeKind.Utc), c[1]);
+ Assert.AreEqual(new DateTime(2000, 12, 1, 0, 0, 0, DateTimeKind.Utc), c[2]);
+
+ Assert.AreEqual(false, eventErrorHandlerCalled);
+ }
+
+ [Test]
+ public void SerializePerson()
+ {
+ PersonError person = new PersonError
+ {
+ Name = "George Michael Bluth",
+ Age = 16,
+ Roles = null,
+ Title = "Mister Manager"
+ };
+
+ string json = JsonConvert.SerializeObject(person, Formatting.Indented);
+
+ Console.WriteLine(json);
+ //{
+ // "Name": "George Michael Bluth",
+ // "Age": 16,
+ // "Title": "Mister Manager"
+ //}
+
+ Assert.AreEqual(@"{
+ ""Name"": ""George Michael Bluth"",
+ ""Age"": 16,
+ ""Title"": ""Mister Manager""
+}", json);
+ }
+
+ [Test]
+ public void DeserializeNestedUnhandled()
+ {
+ List<string> errors = new List<string>();
+
+ string json = @"[[""kjhkjhkjhkjh""]]";
+
+ try
+ {
+ JsonSerializer serializer = new JsonSerializer();
+ serializer.Error += delegate(object sender, ErrorEventArgs args)
+ {
+ // only log an error once
+ if (args.CurrentObject == args.ErrorContext.OriginalObject)
+ errors.Add(args.ErrorContext.Error.Message);
+ };
+
+ serializer.Deserialize(new StringReader(json), typeof(List<List<DateTime>>));
+ }
+ catch
+ {
+ }
+
+ Assert.AreEqual(1, errors.Count);
+ Assert.AreEqual("Could not cast or convert from System.String to System.DateTime.", errors[0]);
+ }
}
} \ No newline at end of file
diff --git a/Src/Newtonsoft.Json.Tests/TestObjects/PersonError.cs b/Src/Newtonsoft.Json.Tests/TestObjects/PersonError.cs
new file mode 100644
index 0000000..7a9483b
--- /dev/null
+++ b/Src/Newtonsoft.Json.Tests/TestObjects/PersonError.cs
@@ -0,0 +1,35 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Runtime.Serialization;
+using System.Text;
+using Newtonsoft.Json.Serialization;
+
+namespace Newtonsoft.Json.Tests.TestObjects
+{
+ public class PersonError
+ {
+ private List<string> _roles;
+
+ public string Name { get; set; }
+ public int Age { get; set; }
+ public List<string> Roles
+ {
+ get
+ {
+ if (_roles == null)
+ throw new Exception("Roles not loaded!");
+
+ return _roles;
+ }
+ set { _roles = value; }
+ }
+ public string Title { get; set; }
+
+ [OnError]
+ internal void HandleError(StreamingContext context, ErrorContext errorContext)
+ {
+ errorContext.Handled = true;
+ }
+ }
+} \ No newline at end of file
diff --git a/Src/Newtonsoft.Json.sln b/Src/Newtonsoft.Json.sln
index 5414e8f..6f1a67c 100644
--- a/Src/Newtonsoft.Json.sln
+++ b/Src/Newtonsoft.Json.sln
@@ -25,7 +25,7 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Doc", "Doc", "{8F9E13D9-418
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\SerializationErrorHandling.html = Doc\SerializationErrorHandling.html
Doc\SerializingCollections.html = Doc\SerializingCollections.html
Doc\SerializingJSON.html = Doc\SerializingJSON.html
Doc\styles.css = Doc\styles.css
diff --git a/Src/Newtonsoft.Json/JsonSerializer.cs b/Src/Newtonsoft.Json/JsonSerializer.cs
index f3babd7..77bdefa 100644
--- a/Src/Newtonsoft.Json/JsonSerializer.cs
+++ b/Src/Newtonsoft.Json/JsonSerializer.cs
@@ -30,6 +30,7 @@ using Newtonsoft.Json.Converters;
using Newtonsoft.Json.Serialization;
using Newtonsoft.Json.Utilities;
using System.Runtime.Serialization;
+using ErrorEventArgs=Newtonsoft.Json.Serialization.ErrorEventArgs;
namespace Newtonsoft.Json
{
@@ -61,6 +62,11 @@ namespace Newtonsoft.Json
};
/// <summary>
+ /// Occurs when the <see cref="JsonSerializer"/> errors during serialization and deserialization.
+ /// </summary>
+ public virtual event EventHandler<ErrorEventArgs> Error;
+
+ /// <summary>
/// Gets or sets the <see cref="IReferenceResolver"/> used by the serializer when resolving references.
/// </summary>
public virtual IReferenceResolver ReferenceResolver
@@ -292,6 +298,9 @@ namespace Newtonsoft.Json
jsonSerializer.DefaultValueHandling = settings.DefaultValueHandling;
jsonSerializer.ConstructorHandling = settings.ConstructorHandling;
+ if (settings.Error != null)
+ jsonSerializer.Error += settings.Error;
+
if (settings.ContractResolver != null)
jsonSerializer.ContractResolver = settings.ContractResolver;
if (settings.ReferenceResolver != null)
@@ -445,5 +454,12 @@ namespace Newtonsoft.Json
matchingConverter = null;
return false;
}
+
+ internal void OnError(ErrorEventArgs e)
+ {
+ EventHandler<ErrorEventArgs> error = Error;
+ if (error != null)
+ error(this, e);
+ }
}
} \ No newline at end of file
diff --git a/Src/Newtonsoft.Json/JsonSerializerSettings.cs b/Src/Newtonsoft.Json/JsonSerializerSettings.cs
index f247ba0..500ce0b 100644
--- a/Src/Newtonsoft.Json/JsonSerializerSettings.cs
+++ b/Src/Newtonsoft.Json/JsonSerializerSettings.cs
@@ -86,6 +86,12 @@ namespace Newtonsoft.Json
public SerializationBinder Binder { get; set; }
/// <summary>
+ /// Gets or sets the error handler called during serialization and deserialization.
+ /// </summary>
+ /// <value>The error handler called during serialization and deserialization.</value>
+ public EventHandler<ErrorEventArgs> Error { get; set;}
+
+ /// <summary>
/// Initializes a new instance of the <see cref="JsonSerializerSettings"/> class.
/// </summary>
public JsonSerializerSettings()
diff --git a/Src/Newtonsoft.Json/Linq/ComponentModel/JPropertyDescriptor.cs b/Src/Newtonsoft.Json/Linq/ComponentModel/JPropertyDescriptor.cs
index b344552..4f5cff4 100644
--- a/Src/Newtonsoft.Json/Linq/ComponentModel/JPropertyDescriptor.cs
+++ b/Src/Newtonsoft.Json/Linq/ComponentModel/JPropertyDescriptor.cs
@@ -153,6 +153,23 @@ namespace Newtonsoft.Json.Linq.ComponentModel
{
get { return _propertyType; }
}
+
+ /// <summary>
+ /// Gets the hash code for the name of the member.
+ /// </summary>
+ /// <value></value>
+ /// <returns>
+ /// The hash code for the name of the member.
+ /// </returns>
+ protected override int NameHashCode
+ {
+ get
+ {
+ // override property to fix up an error in its documentation
+ int nameHashCode = base.NameHashCode;
+ return nameHashCode;
+ }
+ }
}
}
#endif \ No newline at end of file
diff --git a/Src/Newtonsoft.Json/Linq/JContainer.cs b/Src/Newtonsoft.Json/Linq/JContainer.cs
index 13bf662..fc81366 100644
--- a/Src/Newtonsoft.Json/Linq/JContainer.cs
+++ b/Src/Newtonsoft.Json/Linq/JContainer.cs
@@ -98,7 +98,7 @@ namespace Newtonsoft.Json.Linq
#if !SILVERLIGHT
/// <summary>
- /// Raises the <see cref="E:AddingNew"/> event.
+ /// Raises the <see cref="AddingNew"/> event.
/// </summary>
/// <param name="e">The <see cref="AddingNewEventArgs"/> instance containing the event data.</param>
protected virtual void OnAddingNew(AddingNewEventArgs e)
@@ -109,7 +109,7 @@ namespace Newtonsoft.Json.Linq
}
/// <summary>
- /// Raises the <see cref="E:ListChanged"/> event.
+ /// Raises the <see cref="ListChanged"/> event.
/// </summary>
/// <param name="e">The <see cref="ListChangedEventArgs"/> instance containing the event data.</param>
protected virtual void OnListChanged(ListChangedEventArgs e)
diff --git a/Src/Newtonsoft.Json/Linq/JObject.cs b/Src/Newtonsoft.Json/Linq/JObject.cs
index b7a3629..f6a01d1 100644
--- a/Src/Newtonsoft.Json/Linq/JObject.cs
+++ b/Src/Newtonsoft.Json/Linq/JObject.cs
@@ -463,7 +463,7 @@ namespace Newtonsoft.Json.Linq
}
/// <summary>
- /// Raises the <see cref="E:PropertyChanged"/> event with the provided arguments.
+ /// Raises the <see cref="PropertyChanged"/> event with the provided arguments.
/// </summary>
/// <param name="propertyName">Name of the property.</param>
protected virtual void OnPropertyChanged(string propertyName)
@@ -474,7 +474,7 @@ namespace Newtonsoft.Json.Linq
#if !PocketPC && !SILVERLIGHT
/// <summary>
- /// Raises the <see cref="E:PropertyChanging"/> event with the provided arguments.
+ /// Raises the <see cref="PropertyChanging"/> event with the provided arguments.
/// </summary>
/// <param name="propertyName">Name of the property.</param>
protected virtual void OnPropertyChanging(string propertyName)
diff --git a/Src/Newtonsoft.Json/Newtonsoft.Json.Compact.csproj b/Src/Newtonsoft.Json/Newtonsoft.Json.Compact.csproj
index 765c1d0..148bc41 100644
--- a/Src/Newtonsoft.Json/Newtonsoft.Json.Compact.csproj
+++ b/Src/Newtonsoft.Json/Newtonsoft.Json.Compact.csproj
@@ -126,6 +126,7 @@
<Compile Include="Serialization\DefaultReferenceResolver.cs" />
<Compile Include="Serialization\DefaultSerializationBinder.cs" />
<Compile Include="Serialization\ErrorContext.cs" />
+ <Compile Include="Serialization\ErrorEventArgs.cs" />
<Compile Include="Serialization\IContractResolver.cs" />
<Compile Include="Serialization\IReferenceResolver.cs" />
<Compile Include="Serialization\JsonArrayContract.cs" />
diff --git a/Src/Newtonsoft.Json/Newtonsoft.Json.Net20.csproj b/Src/Newtonsoft.Json/Newtonsoft.Json.Net20.csproj
index 160d3cd..e1cdbd1 100644
--- a/Src/Newtonsoft.Json/Newtonsoft.Json.Net20.csproj
+++ b/Src/Newtonsoft.Json/Newtonsoft.Json.Net20.csproj
@@ -144,6 +144,7 @@
<Compile Include="Serialization\DefaultContractResolver.cs" />
<Compile Include="Serialization\DefaultSerializationBinder.cs" />
<Compile Include="Serialization\ErrorContext.cs" />
+ <Compile Include="Serialization\ErrorEventArgs.cs" />
<Compile Include="Serialization\IContractResolver.cs" />
<Compile Include="Serialization\JsonArrayContract.cs" />
<Compile Include="Serialization\JsonContract.cs" />
diff --git a/Src/Newtonsoft.Json/Newtonsoft.Json.Silverlight.csproj b/Src/Newtonsoft.Json/Newtonsoft.Json.Silverlight.csproj
index e811cb9..d6f605f 100644
--- a/Src/Newtonsoft.Json/Newtonsoft.Json.Silverlight.csproj
+++ b/Src/Newtonsoft.Json/Newtonsoft.Json.Silverlight.csproj
@@ -114,6 +114,7 @@
<Compile Include="Serialization\DefaultReferenceResolver.cs" />
<Compile Include="Serialization\DefaultSerializationBinder.cs" />
<Compile Include="Serialization\ErrorContext.cs" />
+ <Compile Include="Serialization\ErrorEventArgs.cs" />
<Compile Include="Serialization\IContractResolver.cs" />
<Compile Include="Serialization\IReferenceResolver.cs" />
<Compile Include="Serialization\JsonArrayContract.cs" />
diff --git a/Src/Newtonsoft.Json/Newtonsoft.Json.csproj b/Src/Newtonsoft.Json/Newtonsoft.Json.csproj
index 81ff65e..867c8a0 100644
--- a/Src/Newtonsoft.Json/Newtonsoft.Json.csproj
+++ b/Src/Newtonsoft.Json/Newtonsoft.Json.csproj
@@ -91,6 +91,7 @@
<Compile Include="Converters\EntityKeyMemberConverter.cs" />
<Compile Include="Converters\StringEnumConverter.cs" />
<Compile Include="ConstructorHandling.cs" />
+ <Compile Include="Serialization\ErrorEventArgs.cs" />
<Compile Include="Linq\ComponentModel\JPropertyDescriptor.cs" />
<Compile Include="Linq\ComponentModel\JTypeDescriptionProvider.cs" />
<Compile Include="Linq\ComponentModel\JTypeDescriptor.cs" />
diff --git a/Src/Newtonsoft.Json/Serialization/ErrorEventArgs.cs b/Src/Newtonsoft.Json/Serialization/ErrorEventArgs.cs
new file mode 100644
index 0000000..f4c7c5b
--- /dev/null
+++ b/Src/Newtonsoft.Json/Serialization/ErrorEventArgs.cs
@@ -0,0 +1,35 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace Newtonsoft.Json.Serialization
+{
+ /// <summary>
+ /// Provides data for the Error event.
+ /// </summary>
+ public class ErrorEventArgs : EventArgs
+ {
+ /// <summary>
+ /// Gets the current object the error event is being raised against.
+ /// </summary>
+ /// <value>The current object the error event is being raised against.</value>
+ public object CurrentObject { get; private set; }
+ /// <summary>
+ /// Gets the error context.
+ /// </summary>
+ /// <value>The error context.</value>
+ public ErrorContext ErrorContext { get; private set; }
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="ErrorEventArgs"/> class.
+ /// </summary>
+ /// <param name="currentObject">The current object.</param>
+ /// <param name="errorContext">The error context.</param>
+ public ErrorEventArgs(object currentObject, ErrorContext errorContext)
+ {
+ CurrentObject = currentObject;
+ ErrorContext = errorContext;
+ }
+ }
+} \ No newline at end of file
diff --git a/Src/Newtonsoft.Json/Serialization/JsonSerializerInternalBase.cs b/Src/Newtonsoft.Json/Serialization/JsonSerializerInternalBase.cs
index de9ccb0..83f8232 100644
--- a/Src/Newtonsoft.Json/Serialization/JsonSerializerInternalBase.cs
+++ b/Src/Newtonsoft.Json/Serialization/JsonSerializerInternalBase.cs
@@ -33,10 +33,19 @@ namespace Newtonsoft.Json.Serialization
{
private ErrorContext _currentErrorContext;
- protected ErrorContext GetErrorContext(object originalObject, object member, Exception error)
+ internal JsonSerializer Serializer { get; private set; }
+
+ protected JsonSerializerInternalBase(JsonSerializer serializer)
+ {
+ ValidationUtils.ArgumentNotNull(serializer, "serializer");
+
+ Serializer = serializer;
+ }
+
+ protected ErrorContext GetErrorContext(object currentObject, object member, Exception error)
{
if (_currentErrorContext == null)
- _currentErrorContext = new ErrorContext(originalObject, member, error);
+ _currentErrorContext = new ErrorContext(currentObject, member, error);
if (_currentErrorContext.Error != error)
throw new InvalidOperationException("Current error context error is different to requested error.");
@@ -51,5 +60,16 @@ namespace Newtonsoft.Json.Serialization
_currentErrorContext = null;
}
+
+ protected bool IsErrorHandled(object currentObject, JsonContract contract, object keyValue, Exception ex)
+ {
+ ErrorContext errorContext = GetErrorContext(currentObject, keyValue, ex);
+ contract.InvokeOnError(currentObject, errorContext);
+
+ if (!errorContext.Handled)
+ Serializer.OnError(new ErrorEventArgs(currentObject, errorContext));
+
+ return errorContext.Handled;
+ }
}
} \ No newline at end of file
diff --git a/Src/Newtonsoft.Json/Serialization/JsonSerializerInternalReader.cs b/Src/Newtonsoft.Json/Serialization/JsonSerializerInternalReader.cs
index 92f7284..38f9f41 100644
--- a/Src/Newtonsoft.Json/Serialization/JsonSerializerInternalReader.cs
+++ b/Src/Newtonsoft.Json/Serialization/JsonSerializerInternalReader.cs
@@ -37,14 +37,10 @@ namespace Newtonsoft.Json.Serialization
{
internal class JsonSerializerInternalReader : JsonSerializerInternalBase
{
- internal readonly JsonSerializer _serializer;
private JsonSerializerProxy _internalSerializer;
- public JsonSerializerInternalReader(JsonSerializer serializer)
+ public JsonSerializerInternalReader(JsonSerializer serializer) : base(serializer)
{
- ValidationUtils.ArgumentNotNull(serializer, "serializer");
-
- _serializer = serializer;
}
public void Populate(JsonReader reader, object target)
@@ -53,7 +49,7 @@ namespace Newtonsoft.Json.Serialization
Type objectType = target.GetType();
- JsonContract contract = _serializer.ContractResolver.ResolveContract(objectType);
+ JsonContract contract = Serializer.ContractResolver.ResolveContract(objectType);
if (reader.TokenType == JsonToken.None)
reader.Read();
@@ -145,10 +141,10 @@ namespace Newtonsoft.Json.Serialization
if (memberConverter != null)
return memberConverter.ReadJson(reader, objectType, GetInternalSerializer());
- if (objectType != null && _serializer.HasClassConverter(objectType, out converter))
+ if (objectType != null && Serializer.HasClassConverter(objectType, out converter))
return converter.ReadJson(reader, objectType, GetInternalSerializer());
- if (objectType != null && _serializer.HasMatchingConverter(objectType, out converter))
+ if (objectType != null && Serializer.HasMatchingConverter(objectType, out converter))
return converter.ReadJson(reader, objectType, GetInternalSerializer());
if (objectType == typeof (JsonRaw))
@@ -219,7 +215,7 @@ namespace Newtonsoft.Json.Serialization
string reference = reader.Value.ToString();
CheckedRead(reader);
- return _serializer.ReferenceResolver.ResolveReference(reference);
+ return Serializer.ReferenceResolver.ResolveReference(reference);
}
else if (string.Equals(propertyName, JsonTypeReflector.TypePropertyName, StringComparison.Ordinal))
{
@@ -228,7 +224,7 @@ namespace Newtonsoft.Json.Serialization
CheckedRead(reader);
- if (_serializer.TypeNameHandling != TypeNameHandling.None)
+ if (Serializer.TypeNameHandling != TypeNameHandling.None)
{
string typeName;
string assemblyName;
@@ -237,7 +233,7 @@ namespace Newtonsoft.Json.Serialization
Type specifiedType;
try
{
- specifiedType = _serializer.Binder.BindToType(assemblyName, typeName);
+ specifiedType = Serializer.Binder.BindToType(assemblyName, typeName);
}
catch (Exception ex)
{
@@ -280,7 +276,7 @@ namespace Newtonsoft.Json.Serialization
if (!HasDefinedType(objectType))
return CreateJObject(reader);
- JsonContract contract = _serializer.ContractResolver.ResolveContract(objectType);
+ JsonContract contract = Serializer.ContractResolver.ResolveContract(objectType);
if (contract == null)
throw new JsonSerializationException("Could not resolve type '{0}' to a JsonContract.".FormatWith(CultureInfo.InvariantCulture, objectType));
@@ -306,7 +302,7 @@ namespace Newtonsoft.Json.Serialization
private JsonArrayContract GetArrayContract(Type objectType)
{
- JsonContract contract = _serializer.ContractResolver.ResolveContract(objectType);
+ JsonContract contract = Serializer.ContractResolver.ResolveContract(objectType);
if (contract == null)
throw new JsonSerializationException("Could not resolve type '{0}' to a JsonContract.".FormatWith(CultureInfo.InvariantCulture, objectType));
@@ -377,7 +373,7 @@ namespace Newtonsoft.Json.Serialization
}
else
{
- if (_serializer.MissingMemberHandling == MissingMemberHandling.Error)
+ if (Serializer.MissingMemberHandling == MissingMemberHandling.Error)
throw new JsonSerializationException("Could not find member '{0}' on object of type '{1}'".FormatWith(CultureInfo.InvariantCulture, memberName, contract.UnderlyingType.Name));
reader.Skip();
@@ -398,7 +394,7 @@ namespace Newtonsoft.Json.Serialization
object currentValue = null;
bool useExistingValue = false;
- if ((_serializer.ObjectCreationHandling == ObjectCreationHandling.Auto || _serializer.ObjectCreationHandling == ObjectCreationHandling.Reuse)
+ if ((Serializer.ObjectCreationHandling == ObjectCreationHandling.Auto || Serializer.ObjectCreationHandling == ObjectCreationHandling.Reuse)
&& (reader.TokenType == JsonToken.StartArray || reader.TokenType == JsonToken.StartObject)
&& property.Readable)
{
@@ -421,10 +417,10 @@ namespace Newtonsoft.Json.Serialization
private bool ShouldSetPropertyValue(JsonProperty property, object value)
{
- if (property.NullValueHandling.GetValueOrDefault(_serializer.NullValueHandling) == NullValueHandling.Ignore && value == null)
+ if (property.NullValueHandling.GetValueOrDefault(Serializer.NullValueHandling) == NullValueHandling.Ignore && value == null)
return false;
- if (property.DefaultValueHandling.GetValueOrDefault(_serializer.DefaultValueHandling) == DefaultValueHandling.Ignore && Equals(value, property.DefaultValue))
+ if (property.DefaultValueHandling.GetValueOrDefault(Serializer.DefaultValueHandling) == DefaultValueHandling.Ignore && Equals(value, property.DefaultValue))
return false;
if (!property.Writable)
@@ -445,7 +441,7 @@ namespace Newtonsoft.Json.Serialization
private IDictionary PopulateDictionary(IWrappedDictionary dictionary, JsonReader reader, JsonDictionaryContract contract, string id)
{
if (id != null)
- _serializer.ReferenceResolver.AddReference(id, dictionary.UnderlyingDictionary);
+ Serializer.ReferenceResolver.AddReference(id, dictionary.UnderlyingDictionary);
contract.InvokeOnDeserializing(dictionary.UnderlyingDictionary);
@@ -465,10 +461,7 @@ namespace Newtonsoft.Json.Serialization
}
catch (Exception ex)
{
- ErrorContext errorContext = GetErrorContext(dictionary.UnderlyingDictionary, keyValue, ex);
- contract.InvokeOnError(dictionary.UnderlyingDictionary, errorContext);
-
- if (errorContext.Handled)
+ if (IsErrorHandled(dictionary, contract, keyValue, ex))
HandleError(reader, initialDepth);
else
throw;
@@ -509,7 +502,7 @@ namespace Newtonsoft.Json.Serialization
object list = wrappedList.UnderlyingCollection;
if (reference != null)
- _serializer.ReferenceResolver.AddReference(reference, list);
+ Serializer.ReferenceResolver.AddReference(reference, list);
contract.InvokeOnDeserializing(list);
@@ -534,10 +527,7 @@ namespace Newtonsoft.Json.Serialization
}
catch (Exception ex)
{
- ErrorContext errorContext = GetErrorContext(list, wrappedList.Count, ex);
- contract.InvokeOnError(list, errorContext);
-
- if (errorContext.Handled)
+ if (IsErrorHandled(list, contract, wrappedList.Count, ex))
HandleError(reader, initialDepth);
else
throw;
@@ -557,7 +547,7 @@ namespace Newtonsoft.Json.Serialization
throw new JsonSerializationException("Could not create an instance of type {0}. Type is an interface or abstract class and cannot be instantated.".FormatWith(CultureInfo.InvariantCulture, contract.UnderlyingType));
if (contract.DefaultContstructor != null &&
- (contract.DefaultContstructor.IsPublic || _serializer.ConstructorHandling == ConstructorHandling.AllowNonPublicDefaultConstructor))
+ (contract.DefaultContstructor.IsPublic || Serializer.ConstructorHandling == ConstructorHandling.AllowNonPublicDefaultConstructor))
{
newObject = contract.DefaultContstructor.Invoke(null);
@@ -601,7 +591,7 @@ namespace Newtonsoft.Json.Serialization
}
else
{
- if (_serializer.MissingMemberHandling == MissingMemberHandling.Error)
+ if (Serializer.MissingMemberHandling == MissingMemberHandling.Error)
throw new JsonSerializationException("Could not find member '{0}' on object of type '{1}'".FormatWith(CultureInfo.InvariantCulture, memberName, objectType.Name));
reader.Skip();
@@ -630,7 +620,7 @@ namespace Newtonsoft.Json.Serialization
object createdObject = contract.ParametrizedConstructor.Invoke(constructorParameters.Values.ToArray());
if (id != null)
- _serializer.ReferenceResolver.AddReference(id, createdObject);
+ Serializer.ReferenceResolver.AddReference(id, createdObject);
contract.InvokeOnDeserializing(createdObject);
@@ -653,7 +643,7 @@ namespace Newtonsoft.Json.Serialization
contract.Properties.Where(m => m.Required).ToDictionary(m => m.PropertyName, m => false);
if (id != null)
- _serializer.ReferenceResolver.AddReference(id, newObject);
+ Serializer.ReferenceResolver.AddReference(id, newObject);
int initialDepth = reader.Depth;
@@ -676,10 +666,7 @@ namespace Newtonsoft.Json.Serialization
}
catch (Exception ex)
{
- ErrorContext errorContext = GetErrorContext(newObject, memberName, ex);
- contract.InvokeOnError(newObject, errorContext);
-
- if (errorContext.Handled)
+ if (IsErrorHandled(newObject, contract, memberName, ex))
HandleError(reader, initialDepth);
else
throw;
@@ -730,6 +717,8 @@ namespace Newtonsoft.Json.Serialization
{
ClearErrorContext();
+ reader.Skip();
+
while (reader.Depth > (initialDepth + 1))
{
reader.Read();
diff --git a/Src/Newtonsoft.Json/Serialization/JsonSerializerInternalWriter.cs b/Src/Newtonsoft.Json/Serialization/JsonSerializerInternalWriter.cs
index 1dd24ee..9b615bb 100644
--- a/Src/Newtonsoft.Json/Serialization/JsonSerializerInternalWriter.cs
+++ b/Src/Newtonsoft.Json/Serialization/JsonSerializerInternalWriter.cs
@@ -38,7 +38,6 @@ namespace Newtonsoft.Json.Serialization
{
internal class JsonSerializerInternalWriter : JsonSerializerInternalBase
{
- internal readonly JsonSerializer _serializer;
private JsonSerializerProxy _internalSerializer;
private List<object> _serializeStack;
@@ -53,11 +52,8 @@ namespace Newtonsoft.Json.Serialization
}
}
- public JsonSerializerInternalWriter(JsonSerializer serializer)
+ public JsonSerializerInternalWriter(JsonSerializer serializer) : base(serializer)
{
- ValidationUtils.ArgumentNotNull(serializer, "serializer");
-
- _serializer = serializer;
}
public void Serialize(JsonWriter jsonWriter, object value)
@@ -85,8 +81,8 @@ namespace Newtonsoft.Json.Serialization
writer.WriteNull();
}
else if (converter != null
- || _serializer.HasClassConverter(value.GetType(), out converter)
- || _serializer.HasMatchingConverter(value.GetType(), out converter))
+ || Serializer.HasClassConverter(value.GetType(), out converter)
+ || Serializer.HasMatchingConverter(value.GetType(), out converter))
{
SerializeConvertable(writer, converter, value);
}
@@ -96,7 +92,7 @@ namespace Newtonsoft.Json.Serialization
}
else if (value is JToken)
{
- ((JToken)value).WriteTo(writer, (_serializer.Converters != null) ? _serializer.Converters.ToArray() : null);
+ ((JToken)value).WriteTo(writer, (Serializer.Converters != null) ? Serializer.Converters.ToArray() : null);
}
else if (value is JsonRaw)
{
@@ -104,7 +100,7 @@ namespace Newtonsoft.Json.Serialization
}
else
{
- JsonContract contract = _serializer.ContractResolver.ResolveContract(value.GetType());
+ JsonContract contract = Serializer.ContractResolver.ResolveContract(value.GetType());
if (contract is JsonObjectContract)
{
@@ -147,7 +143,7 @@ namespace Newtonsoft.Json.Serialization
if (isReference == null)
{
- JsonContract memberTypeContract = _serializer.ContractResolver.ResolveContract(value.GetType());
+ JsonContract memberTypeContract = Serializer.ContractResolver.ResolveContract(value.GetType());
if (memberTypeContract != null)
isReference = memberTypeContract.IsReference;
}
@@ -155,19 +151,19 @@ namespace Newtonsoft.Json.Serialization
if (isReference == null)
{
if (value is IList)
- isReference = HasFlag(_serializer.PreserveReferencesHandling, PreserveReferencesHandling.Arrays);
+ isReference = HasFlag(Serializer.PreserveReferencesHandling, PreserveReferencesHandling.Arrays);
else if (value is IDictionary)
- isReference = HasFlag(_serializer.PreserveReferencesHandling, PreserveReferencesHandling.Objects);
+ isReference = HasFlag(Serializer.PreserveReferencesHandling, PreserveReferencesHandling.Objects);
else if (value is IEnumerable)
- isReference = HasFlag(_serializer.PreserveReferencesHandling, PreserveReferencesHandling.Arrays);
+ isReference = HasFlag(Serializer.PreserveReferencesHandling, PreserveReferencesHandling.Arrays);
else
- isReference = HasFlag(_serializer.PreserveReferencesHandling, PreserveReferencesHandling.Objects);
+ isReference = HasFlag(Serializer.PreserveReferencesHandling, PreserveReferencesHandling.Objects);
}
if (!isReference.Value)
return false;
- return _serializer.ReferenceResolver.IsReferenced(value);
+ return Serializer.ReferenceResolver.IsReferenced(value);
}
private void WriteMemberInfoProperty(JsonWriter writer, object value, JsonProperty property)
@@ -181,10 +177,10 @@ namespace Newtonsoft.Json.Serialization
{
object memberValue = ReflectionUtils.GetMemberValue(member, value);
- if (property.NullValueHandling.GetValueOrDefault(_serializer.NullValueHandling) == NullValueHandling.Ignore && memberValue == null)
+ if (property.NullValueHandling.GetValueOrDefault(Serializer.NullValueHandling) == NullValueHandling.Ignore && memberValue == null)
return;
- if (property.DefaultValueHandling.GetValueOrDefault(_serializer.DefaultValueHandling) == DefaultValueHandling.Ignore && Equals(memberValue, defaultValue))
+ if (property.DefaultValueHandling.GetValueOrDefault(Serializer.DefaultValueHandling) == DefaultValueHandling.Ignore && Equals(memberValue, defaultValue))
return;
if (ShouldWriteReference(memberValue, property))
@@ -206,7 +202,7 @@ namespace Newtonsoft.Json.Serialization
{
if (SerializeStack.IndexOf(value) != -1)
{
- switch (referenceLoopHandling.GetValueOrDefault(_serializer.ReferenceLoopHandling))
+ switch (referenceLoopHandling.GetValueOrDefault(Serializer.ReferenceLoopHandling))
{
case ReferenceLoopHandling.Error:
throw new JsonSerializationException("Self referencing loop");
@@ -215,7 +211,7 @@ namespace Newtonsoft.Json.Serialization
case ReferenceLoopHandling.Serialize:
return true;
default:
- throw new InvalidOperationException("Unexpected ReferenceLoopHandling value: '{0}'".FormatWith(CultureInfo.InvariantCulture, _serializer.ReferenceLoopHandling));
+ throw new InvalidOperationException("Unexpected ReferenceLoopHandling value: '{0}'".FormatWith(CultureInfo.InvariantCulture, Serializer.ReferenceLoopHandling));
}
}
@@ -226,7 +222,7 @@ namespace Newtonsoft.Json.Serialization
{
writer.WriteStartObject();
writer.WritePropertyName(JsonTypeReflector.RefPropertyName);
- writer.WriteValue(_serializer.ReferenceResolver.GetReference(value));
+ writer.WriteValue(Serializer.ReferenceResolver.GetReference(value));
writer.WriteEndObject();
}
@@ -274,13 +270,13 @@ namespace Newtonsoft.Json.Serialization
SerializeStack.Add(value);
writer.WriteStartObject();
- bool isReference = contract.IsReference ?? HasFlag(_serializer.PreserveReferencesHandling, PreserveReferencesHandling.Objects);
+ bool isReference = contract.IsReference ?? HasFlag(Serializer.PreserveReferencesHandling, PreserveReferencesHandling.Objects);
if (isReference)
{
writer.WritePropertyName(JsonTypeReflector.IdPropertyName);
- writer.WriteValue(_serializer.ReferenceResolver.GetReference(value));
+ writer.WriteValue(Serializer.ReferenceResolver.GetReference(value));
}
- if (HasFlag(_serializer.TypeNameHandling, TypeNameHandling.Objects))
+ if (HasFlag(Serializer.TypeNameHandling, TypeNameHandling.Objects))
{
WriteTypeProperty(writer, contract.UnderlyingType);
}
@@ -296,10 +292,7 @@ namespace Newtonsoft.Json.Serialization
}
catch (Exception ex)
{
- ErrorContext errorContext = GetErrorContext(value, property.Member.Name, ex);
- contract.InvokeOnError(value, errorContext);
-
- if (errorContext.Handled)
+ if (IsErrorHandled(value, contract, property.Member.Name, ex))
HandleError(writer, initialDepth);
else
throw;
@@ -358,8 +351,8 @@ namespace Newtonsoft.Json.Serialization
SerializeStack.Add(values);
- bool isReference = contract.IsReference ?? HasFlag(_serializer.PreserveReferencesHandling, PreserveReferencesHandling.Arrays);
- bool includeTypeDetails = HasFlag(_serializer.TypeNameHandling, TypeNameHandling.Arrays);
+ bool isReference = contract.IsReference ?? HasFlag(Serializer.PreserveReferencesHandling, PreserveReferencesHandling.Arrays);
+ bool includeTypeDetails = HasFlag(Serializer.TypeNameHandling, TypeNameHandling.Arrays);
if (isReference || includeTypeDetails)
{
@@ -368,7 +361,7 @@ namespace Newtonsoft.Json.Serialization
if (isReference)
{
writer.WritePropertyName(JsonTypeReflector.IdPropertyName);
- writer.WriteValue(_serializer.ReferenceResolver.GetReference(values));
+ writer.WriteValue(Serializer.ReferenceResolver.GetReference(values));
}
if (includeTypeDetails)
{
@@ -401,10 +394,7 @@ namespace Newtonsoft.Json.Serialization
}
catch (Exception ex)
{
- ErrorContext errorContext = GetErrorContext(values, i, ex);
- contract.InvokeOnError(values, errorContext);
-
- if (errorContext.Handled)
+ if (IsErrorHandled(values, contract, i, ex))
HandleError(writer, initialDepth);
else
throw;
@@ -430,13 +420,13 @@ namespace Newtonsoft.Json.Serialization
SerializeStack.Add(values);
writer.WriteStartObject();
- bool isReference = contract.IsReference ?? HasFlag(_serializer.PreserveReferencesHandling, PreserveReferencesHandling.Objects);
+ bool isReference = contract.IsReference ?? HasFlag(Serializer.PreserveReferencesHandling, PreserveReferencesHandling.Objects);
if (isReference)
{
writer.WritePropertyName(JsonTypeReflector.IdPropertyName);
- writer.WriteValue(_serializer.ReferenceResolver.GetReference(values));
+ writer.WriteValue(Serializer.ReferenceResolver.GetReference(values));
}
- if (HasFlag(_serializer.TypeNameHandling, TypeNameHandling.Objects))
+ if (HasFlag(Serializer.TypeNameHandling, TypeNameHandling.Objects))
{
WriteTypeProperty(writer, values.GetType());
}
@@ -468,10 +458,7 @@ namespace Newtonsoft.Json.Serialization
}
catch (Exception ex)
{
- ErrorContext errorContext = GetErrorContext(values, propertyName, ex);
- contract.InvokeOnError(values, errorContext);
-
- if (errorContext.Handled)
+ if (IsErrorHandled(values, contract, propertyName, ex))
HandleError(writer, initialDepth);
else
throw;
diff --git a/Src/Newtonsoft.Json/Serialization/JsonSerializerProxy.cs b/Src/Newtonsoft.Json/Serialization/JsonSerializerProxy.cs
index 64bf989..a55bd8d 100644
--- a/Src/Newtonsoft.Json/Serialization/JsonSerializerProxy.cs
+++ b/Src/Newtonsoft.Json/Serialization/JsonSerializerProxy.cs
@@ -35,6 +35,12 @@ namespace Newtonsoft.Json.Serialization
private readonly JsonSerializerInternalWriter _serializerWriter;
private readonly JsonSerializer _serializer;
+ public override event EventHandler<ErrorEventArgs> Error
+ {
+ add { _serializer.Error += value; }
+ remove { _serializer.Error -= value; }
+ }
+
public override IReferenceResolver ReferenceResolver
{
get { return _serializer.ReferenceResolver; }
@@ -111,7 +117,7 @@ namespace Newtonsoft.Json.Serialization
ValidationUtils.ArgumentNotNull(serializerReader, "serializerReader");
_serializerReader = serializerReader;
- _serializer = serializerReader._serializer;
+ _serializer = serializerReader.Serializer;
}
public JsonSerializerProxy(JsonSerializerInternalWriter serializerWriter)
@@ -119,7 +125,7 @@ namespace Newtonsoft.Json.Serialization
ValidationUtils.ArgumentNotNull(serializerWriter, "serializerWriter");
_serializerWriter = serializerWriter;
- _serializer = serializerWriter._serializer;
+ _serializer = serializerWriter.Serializer;
}
internal override object DeserializeInternal(JsonReader reader, Type objectType)