-Documentation

-Added Error event to JsonSerializer
This commit is contained in:
JamesNK
2009-10-11 04:23:35 +00:00
parent 0a45159376
commit b313445e01
25 changed files with 516 additions and 88 deletions
+172
View File
@@ -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>
+4 -3
View File
@@ -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>
+2
View File
@@ -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>
+1
View File
@@ -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" />
@@ -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" />
@@ -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" />
@@ -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" />
@@ -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" />
@@ -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]);
}
}
}
@@ -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;
}
}
}
+1 -1
View File
@@ -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
+16
View File
@@ -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
{
@@ -60,6 +61,11 @@ namespace Newtonsoft.Json
#endif
};
/// <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>
@@ -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);
}
}
}
@@ -85,6 +85,12 @@ namespace Newtonsoft.Json
/// <value>The binder.</value>
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>
@@ -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
+2 -2
View File
@@ -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)
+2 -2
View File
@@ -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)
@@ -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" />
@@ -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" />
@@ -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" />
@@ -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" />
@@ -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;
}
}
}
@@ -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;
}
}
}
@@ -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();
@@ -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;
@@ -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)