-Documentation
-Added Error event to JsonSerializer
This commit is contained in:
@@ -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><<span style="color: blue;">string</span>> errors = <span style="color: blue;">new</span> <span style="color: #2b91af;">List</span><<span style="color: blue;">string</span>>();</pre>
|
||||
<pre style="margin: 0px;"> </pre>
|
||||
<pre style="margin: 0px;"><span style="color: #2b91af;">List</span><<span style="color: #2b91af;">DateTime</span>> c = <span style="color: #2b91af;">JsonConvert</span>.DeserializeObject<<span style="color: #2b91af;">List</span><<span style="color: #2b91af;">DateTime</span>>>(<span style="color: #a31515;">@"[</span></pre>
|
||||
<pre style="margin: 0px;"><span style="color: #a31515;"> ""2009-09-09T00:00:00Z"",</span></pre>
|
||||
<pre style="margin: 0px;"><span style="color: #a31515;"> ""I am not a date and will error!"",</span></pre>
|
||||
<pre style="margin: 0px;"><span style="color: #a31515;"> [</span></pre>
|
||||
<pre style="margin: 0px;"><span style="color: #a31515;"> 1</span></pre>
|
||||
<pre style="margin: 0px;"><span style="color: #a31515;"> ],</span></pre>
|
||||
<pre style="margin: 0px;"><span style="color: #a31515;"> ""1977-02-20T00:00:00Z"",</span></pre>
|
||||
<pre style="margin: 0px;"><span style="color: #a31515;"> null,</span></pre>
|
||||
<pre style="margin: 0px;"><span style="color: #a31515;"> ""2000-12-01T00:00:00Z""</span></pre>
|
||||
<pre style="margin: 0px;"><span style="color: #a31515;">]"</span>,</pre>
|
||||
<pre style="margin: 0px;"> <span style="color: blue;">new</span> <span style="color: #2b91af;">JsonSerializerSettings</span></pre>
|
||||
<pre style="margin: 0px;"> {</pre>
|
||||
<pre style="margin: 0px;"> 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;"> {</pre>
|
||||
<pre style="margin: 0px;"> errors.Add(args.ErrorContext.Error.Message);</pre>
|
||||
<pre style="margin: 0px;"> args.ErrorContext.Handled = <span style="color: blue;">true</span>;</pre>
|
||||
<pre style="margin: 0px;"> },</pre>
|
||||
<pre style="margin: 0px;"> Converters = { <span style="color: blue;">new</span> <span style="color: #2b91af;">IsoDateTimeConverter</span>() }</pre>
|
||||
<pre style="margin: 0px;"> });</pre>
|
||||
<pre style="margin: 0px;"> </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;"> </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;"> {</pre>
|
||||
<pre style="margin: 0px;"> <span style="color: green;">// only log an error once</span></pre>
|
||||
<pre style="margin: 0px;"> <span style="color: blue;">if</span> (args.CurrentObject == args.ErrorContext.OriginalObject)</pre>
|
||||
<pre style="margin: 0px;"> errors.Add(args.ErrorContext.Error.Message);</pre>
|
||||
<pre style="margin: 0px;"> };</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;"> <span style="color: blue;">private</span> <span style="color: #2b91af;">List</span><<span style="color: blue;">string</span>> _roles;</pre>
|
||||
<pre style="margin: 0px;"> </pre>
|
||||
<pre style="margin: 0px;"> <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;"> <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;"> <span style="color: blue;">public</span> <span style="color: #2b91af;">List</span><<span style="color: blue;">string</span>> Roles</pre>
|
||||
<pre style="margin: 0px;"> {</pre>
|
||||
<pre style="margin: 0px;"> <span style="color: blue;">get</span></pre>
|
||||
<pre style="margin: 0px;"> {</pre>
|
||||
<pre style="margin: 0px;"> <span style="color: blue;">if</span> (_roles == <span style="color: blue;">null</span>)</pre>
|
||||
<pre style="margin: 0px;"> <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;"> </pre>
|
||||
<pre style="margin: 0px;"> <span style="color: blue;">return</span> _roles;</pre>
|
||||
<pre style="margin: 0px;"> }</pre>
|
||||
<pre style="margin: 0px;"> <span style="color: blue;">set</span> { _roles = <span style="color: blue;">value</span>; }</pre>
|
||||
<pre style="margin: 0px;"> }</pre>
|
||||
<pre style="margin: 0px;"> <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;"> </pre>
|
||||
<pre style="margin: 0px;"> [<span style="color: #2b91af;">OnError</span>]</pre>
|
||||
<pre style="margin: 0px;"> <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;"> {</pre>
|
||||
<pre style="margin: 0px;"> errorContext.Handled = <span style="color: blue;">true</span>;</pre>
|
||||
<pre style="margin: 0px;"> }</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;"> {</pre>
|
||||
<pre style="margin: 0px;"> Name = <span style="color: #a31515;">"George Michael Bluth"</span>,</pre>
|
||||
<pre style="margin: 0px;"> Age = 16,</pre>
|
||||
<pre style="margin: 0px;"> Roles = <span style="color: blue;">null</span>,</pre>
|
||||
<pre style="margin: 0px;"> Title = <span style="color: #a31515;">"Mister Manager"</span></pre>
|
||||
<pre style="margin: 0px;"> };</pre>
|
||||
<pre style="margin: 0px;"> </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;"> </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;">// "Name": "George Michael Bluth",</span></pre>
|
||||
<pre style="margin: 0px;"><span style="color: green;">// "Age": 16,</span></pre>
|
||||
<pre style="margin: 0px;"><span style="color: green;">// "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>
|
||||
@@ -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>
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
<namespaceSummaryItem name="Newtonsoft.Json" isDocumented="True">The <b>Newtonsoft.Json</b> namespace provides classes that are used to implement the core services of the framework.</namespaceSummaryItem>
|
||||
<namespaceSummaryItem name="Newtonsoft.Json.Converters" isDocumented="True">The <b>Newtonsoft.Json.Converters</b> namespace provides classes that inherit from <a href="T_Newtonsoft_Json_JsonConverter.htm">JsonConverter</a>.</namespaceSummaryItem>
|
||||
<namespaceSummaryItem name="Newtonsoft.Json.Linq" isDocumented="True">The <b>Newtonsoft.Json.Linq</b> namespace provides classes that are used to implement LINQ to JSON.</namespaceSummaryItem>
|
||||
<namespaceSummaryItem name="Newtonsoft.Json.Linq.ComponentModel" isDocumented="True">The <b>Newtonsoft.Json.Linq.ComponentModel</b> namespace provides classes for LINQ to JSON databinding.</namespaceSummaryItem>
|
||||
<namespaceSummaryItem name="Newtonsoft.Json.Schema" isDocumented="True">The <b>Newtonsoft.Json.Schema</b> namespace provides classes that are used to implement JSON schema.</namespaceSummaryItem>
|
||||
<namespaceSummaryItem name="Newtonsoft.Json.Serialization" isDocumented="True">The <b>Newtonsoft.Json.Linq</b> 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>
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
|
||||
Reference in New Issue
Block a user