Skip to content

Commit b313445

Browse files
committed
-Documentation
-Added Error event to JsonSerializer
1 parent 0a45159 commit b313445

25 files changed

+516
-88
lines changed
Lines changed: 172 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,172 @@
1+
<html>
2+
3+
<head>
4+
<title>Serialization Error Handling</title>
5+
<link href="styles.css" rel="stylesheet" type="text/css" />
6+
<link href="custom.css" rel="stylesheet" type="text/css" />
7+
</head>
8+
9+
<body>
10+
11+
<div id="control">
12+
<span class="productTitle">Json.NET - Quick Starts & API Documentation</span><br />
13+
<span class="topicTitle">Serialization Error Handling</span></div>
14+
15+
<div id="content">
16+
<span style="color: DarkGray"> </span>
17+
18+
<p>Json.NET supports error handling during serialization and deserialization. Error handling lets
19+
you catch an error and choose whether to handle it and continue with serialization or let the error
20+
bubble up and be thrown in your application.</p>
21+
<p>Error handling is defined through two methods:
22+
the Error event on JsonSerializer and the OnErrorAttribute.</p>
23+
<h3>Error Event</h3>
24+
25+
<p>
26+
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
27+
exception is thrown while serializing or deserialing JSON. Like all settings found on JsonSerializer
28+
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>
29+
30+
<div class="overflowpanel"> <div class="code">
31+
<div style="font-family: Courier New; font-size: 10pt; color: black;">
32+
<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>
33+
<pre style="margin: 0px;">&nbsp;</pre>
34+
<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>
35+
<pre style="margin: 0px;"><span style="color: #a31515;">&nbsp; ""2009-09-09T00:00:00Z"",</span></pre>
36+
<pre style="margin: 0px;"><span style="color: #a31515;">&nbsp; ""I am not a date and will error!"",</span></pre>
37+
<pre style="margin: 0px;"><span style="color: #a31515;">&nbsp; [</span></pre>
38+
<pre style="margin: 0px;"><span style="color: #a31515;">&nbsp; &nbsp; 1</span></pre>
39+
<pre style="margin: 0px;"><span style="color: #a31515;">&nbsp; ],</span></pre>
40+
<pre style="margin: 0px;"><span style="color: #a31515;">&nbsp; ""1977-02-20T00:00:00Z"",</span></pre>
41+
<pre style="margin: 0px;"><span style="color: #a31515;">&nbsp; null,</span></pre>
42+
<pre style="margin: 0px;"><span style="color: #a31515;">&nbsp; ""2000-12-01T00:00:00Z""</span></pre>
43+
<pre style="margin: 0px;"><span style="color: #a31515;">]"</span>,</pre>
44+
<pre style="margin: 0px;">&nbsp; <span style="color: blue;">new</span> <span style="color: #2b91af;">JsonSerializerSettings</span></pre>
45+
<pre style="margin: 0px;">&nbsp; &nbsp; {</pre>
46+
<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>
47+
<pre style="margin: 0px;">&nbsp; &nbsp; &nbsp; &nbsp; {</pre>
48+
<pre style="margin: 0px;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; errors.Add(args.ErrorContext.Error.Message);</pre>
49+
<pre style="margin: 0px;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; args.ErrorContext.Handled = <span style="color: blue;">true</span>;</pre>
50+
<pre style="margin: 0px;">&nbsp; &nbsp; &nbsp; &nbsp; },</pre>
51+
<pre style="margin: 0px;">&nbsp; &nbsp; &nbsp; Converters = { <span style="color: blue;">new</span> <span style="color: #2b91af;">IsoDateTimeConverter</span>() }</pre>
52+
<pre style="margin: 0px;">&nbsp; &nbsp; });</pre>
53+
<pre style="margin: 0px;">&nbsp;</pre>
54+
<pre style="margin: 0px;"><span style="color: green;">// 2009-09-09T00:00:00Z</span></pre>
55+
<pre style="margin: 0px;"><span style="color: green;">// 1977-02-20T00:00:00Z</span></pre>
56+
<pre style="margin: 0px;"><span style="color: green;">// 2000-12-01T00:00:00Z</span></pre>
57+
<pre style="margin: 0px;">&nbsp;</pre>
58+
<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>
59+
<pre style="margin: 0px;"><span style="color: green;">// Unexpected token parsing date. Expected String, got StartArray.</span></pre>
60+
<pre style="margin: 0px;"><span style="color: green;">// Cannot convert null value to System.DateTime.</span></pre>
61+
</div>
62+
</div>
63+
</div>
64+
<p>
65+
In this example we are deserializing a JSON array to a collection of DateTimes. On the JsonSerializerSettings
66+
a handler has been assigned to the Error event which will log the error message and mark the error as handled.
67+
</p>
68+
<p>
69+
The result of deserializing the JSON is three successfully deserialized dates and three error messages:
70+
one for the badly formatted string, "I am not a date and will error!", one for the nested JSON array and one
71+
for the null value since the list doesn't allow nullable DateTimes. The event handler has logged these messages
72+
and Json.NET has continued on deserializing the JSON because the errors were marked as handled.
73+
</p>
74+
<p>
75+
One thing to note with error handling in Json.NET is that an unhandled error will bubble up and raise the event
76+
on each of its parents, e.g. an unhandled error when serializing a collection of objects will be raised twice,
77+
once against the object and then again on the collection. This will let you handle an error either where it
78+
occurred or on one of its parents.
79+
</p>
80+
81+
82+
<div class="overflowpanel"> <div class="code">
83+
<div style="font-family: Courier New; font-size: 10pt; color: black;">
84+
<pre style="margin: 0px;"><span style="color: #2b91af;">JsonSerializer</span> serializer = <span style="color: blue;">new</span> <span style="color: #2b91af;">JsonSerializer</span>();</pre>
85+
<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>
86+
<pre style="margin: 0px;">&nbsp; {</pre>
87+
<pre style="margin: 0px;">&nbsp; &nbsp; <span style="color: green;">// only log an error once</span></pre>
88+
<pre style="margin: 0px;">&nbsp; &nbsp; <span style="color: blue;">if</span> (args.CurrentObject == args.ErrorContext.OriginalObject)</pre>
89+
<pre style="margin: 0px;">&nbsp; &nbsp; &nbsp; errors.Add(args.ErrorContext.Error.Message);</pre>
90+
<pre style="margin: 0px;">&nbsp; };</pre>
91+
</div>
92+
</div></div>
93+
94+
<p>If you aren't immediately handling an error and only want to perform an action against it once then
95+
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.
96+
OriginalObject is the object that threw the error and CurrentObject is the object that the event is being raised
97+
against. They will only equal the first time the event is raised against the OriginalObject.</p>
98+
99+
<h3>OnErrorAttribute</h3>
100+
101+
<p>
102+
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.
103+
To use it you simply place the attribute on a method which takes the correct parameters: a StreamingContext and a ErrorContext.
104+
The name of the method doesn't matter. </p>
105+
<div class="overflowpanel"> <div class="code">
106+
107+
<div style="font-family: Courier New; font-size: 10pt; color: black;">
108+
<pre style="margin: 0px;"><span style="color: blue;">public</span> <span style="color: blue;">class</span> <span style="color: #2b91af;">PersonError</span></pre>
109+
<pre style="margin: 0px;">{</pre>
110+
<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>
111+
<pre style="margin: 0px;">&nbsp;</pre>
112+
<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>
113+
<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>
114+
<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>
115+
<pre style="margin: 0px;">&nbsp; {</pre>
116+
<pre style="margin: 0px;">&nbsp; &nbsp; <span style="color: blue;">get</span></pre>
117+
<pre style="margin: 0px;">&nbsp; &nbsp; {</pre>
118+
<pre style="margin: 0px;">&nbsp; &nbsp; &nbsp; <span style="color: blue;">if</span> (_roles == <span style="color: blue;">null</span>)</pre>
119+
<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>
120+
<pre style="margin: 0px;">&nbsp;</pre>
121+
<pre style="margin: 0px;">&nbsp; &nbsp; &nbsp; <span style="color: blue;">return</span> _roles;</pre>
122+
<pre style="margin: 0px;">&nbsp; &nbsp; }</pre>
123+
<pre style="margin: 0px;">&nbsp; &nbsp; <span style="color: blue;">set</span> { _roles = <span style="color: blue;">value</span>; }</pre>
124+
<pre style="margin: 0px;">&nbsp; }</pre>
125+
<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>
126+
<pre style="margin: 0px;">&nbsp;</pre>
127+
<pre style="margin: 0px;">&nbsp; [<span style="color: #2b91af;">OnError</span>]</pre>
128+
<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>
129+
<pre style="margin: 0px;">&nbsp; {</pre>
130+
<pre style="margin: 0px;">&nbsp; &nbsp; errorContext.Handled = <span style="color: blue;">true</span>;</pre>
131+
<pre style="margin: 0px;">&nbsp; }</pre>
132+
<pre style="margin: 0px;">}</pre>
133+
</div>
134+
</div></div>
135+
<p>
136+
In this example accessing the the Roles property will throw an exception when no roles have
137+
been set. The HandleError method will set the error when serializing Roles as handled and allow Json.NET to continue
138+
serializing the class.
139+
</p>
140+
141+
<div class="overflowpanel"> <div class="code">
142+
<div style="font-family: Courier New; font-size: 10pt; color: black;">
143+
<pre style="margin: 0px;"><span style="color: #2b91af;">PersonError</span> person = <span style="color: blue;">new</span> <span style="color: #2b91af;">PersonError</span></pre>
144+
<pre style="margin: 0px;">&nbsp; {</pre>
145+
<pre style="margin: 0px;">&nbsp; &nbsp; Name = <span style="color: #a31515;">"George Michael Bluth"</span>,</pre>
146+
<pre style="margin: 0px;">&nbsp; &nbsp; Age = 16,</pre>
147+
<pre style="margin: 0px;">&nbsp; &nbsp; Roles = <span style="color: blue;">null</span>,</pre>
148+
<pre style="margin: 0px;">&nbsp; &nbsp; Title = <span style="color: #a31515;">"Mister Manager"</span></pre>
149+
<pre style="margin: 0px;">&nbsp; };</pre>
150+
<pre style="margin: 0px;">&nbsp;</pre>
151+
<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>
152+
<pre style="margin: 0px;">&nbsp;</pre>
153+
<pre style="margin: 0px;"><span style="color: #2b91af;">Console</span>.WriteLine(json);</pre>
154+
<pre style="margin: 0px;"><span style="color: green;">//{</span></pre>
155+
<pre style="margin: 0px;"><span style="color: green;">//&nbsp; "Name": "George Michael Bluth",</span></pre>
156+
<pre style="margin: 0px;"><span style="color: green;">//&nbsp; "Age": 16,</span></pre>
157+
<pre style="margin: 0px;"><span style="color: green;">//&nbsp; "Title": "Mister Manager"</span></pre>
158+
<pre style="margin: 0px;"><span style="color: green;">//}</span></pre>
159+
</div>
160+
</div></div>
161+
162+
163+
<div id="footer">
164+
165+
166+
167+
</div>
168+
</div>
169+
170+
</body>
171+
172+
</html>

Src/Doc/SerializingJSON.html

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -92,12 +92,13 @@ <h5>DefaultValueHandling</h5>
9292
the member's DefaultValueAttribute. Include or ignore.</p>
9393
<h5>ObjectCreationHandling</h5>
9494
<p>Controls how objects are created during deserialization. Auto, reuse, replace.</p>
95+
<h5>TypeNameHandling</h5>
96+
<p>Controls whether .NET type names are included in serialized JSON and read during deserialization when creating objects. None, Objects, Arrays or All.</p>
97+
<h5>ConstructorHandling</h5>
98+
<p>Controls how constructors are used when initializing objects during deserialization. Default or AllowNonPublicDefaultConstructor.</p>
9599
<h5>Converters</h5>
96100
<p>A collection of JsonConverters that will be used during serialization and
97101
deserialization.</p>
98-
<h5>TypeNameHandling</h5>
99-
<p>Controls how .NET type names are used when serializing and deserializing JSON. If
100-
type names are SDFSDFSDF</p>
101102

102103

103104
<h3>JsonConverters</h3>

Src/Doc/doc.shfb

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
<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>
88
<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>
99
<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>
10+
<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>
1011
<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>
1112
<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>
1213
<namespaceSummaryItem name="Newtonsoft.Json.Utilities" isDocumented="False" />
@@ -25,6 +26,7 @@
2526
<contentItem sourcePath=".\SerializationCallbacks.html" destPath="" excludeItems="False" />
2627
<contentItem sourcePath=".\SerializationAttributes.html" destPath="" excludeItems="False" />
2728
<contentItem sourcePath=".\SerializingCollections.html" destPath="" excludeItems="False" />
29+
<contentItem sourcePath=".\SerializationErrorHandling.html" destPath="" excludeItems="False" />
2830
</additionalContent>
2931
<ProjectSummary />
3032
<MissingTags>Summary, Parameter, Returns, AutoDocumentCtors, Namespace, TypeParameter</MissingTags>

Src/Doc/doc.sitemap

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
<siteMapNode title="Serializing Dates in JSON" url=".\DatesInJSON.html" />
77
<siteMapNode title="Serializing Collections" url=".\SerializingCollections.html" />
88
<siteMapNode title="Serialization Callbacks" url=".\SerializationCallbacks.html" />
9+
<siteMapNode title="Serialization Error Handling" url=".\SerializationErrorHandling.html" />
910
<siteMapNode title="Serialization and Preserving Object References" url=".\PreserveObjectReferences.html" />
1011
<siteMapNode title="CustomCreationConverter" url=".\CustomCreationConverter.html" />
1112
<siteMapNode title="Contract Resolvers" url=".\ContractResolver.html" />

Src/Newtonsoft.Json.Tests/Newtonsoft.Json.Tests.Compact.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -120,6 +120,7 @@
120120
<Compile Include="TestObjects\NonRequest.cs" />
121121
<Compile Include="TestObjects\NullableDateTimeTestClass.cs" />
122122
<Compile Include="TestObjects\ObjectArrayPropertyTest.cs" />
123+
<Compile Include="TestObjects\PersonError.cs" />
123124
<Compile Include="TestObjects\PersonRaw.cs" />
124125
<Compile Include="TestObjects\PhoneNumber.cs" />
125126
<Compile Include="TestObjects\PrivateConstructorTestClass.cs" />

Src/Newtonsoft.Json.Tests/Newtonsoft.Json.Tests.Net20.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,7 @@
8787
<Compile Include="TestObjects\NonRequest.cs" />
8888
<Compile Include="TestObjects\ObjectArrayPropertyTest.cs" />
8989
<Compile Include="Serialization\PopulateTests.cs" />
90+
<Compile Include="TestObjects\PersonError.cs" />
9091
<Compile Include="TestObjects\PrivateConstructorTestClass.cs" />
9192
<Compile Include="TestObjects\PrivateConstructorWithPublicParametizedConstructorTestClass.cs" />
9293
<Compile Include="TestObjects\PropertyCase.cs" />

Src/Newtonsoft.Json.Tests/Newtonsoft.Json.Tests.Silverlight.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -126,6 +126,7 @@
126126
<Compile Include="TestObjects\NonRequest.cs" />
127127
<Compile Include="TestObjects\NullableDateTimeTestClass.cs" />
128128
<Compile Include="TestObjects\ObjectArrayPropertyTest.cs" />
129+
<Compile Include="TestObjects\PersonError.cs" />
129130
<Compile Include="TestObjects\PersonRaw.cs" />
130131
<Compile Include="TestObjects\PhoneNumber.cs" />
131132
<Compile Include="TestObjects\PrivateConstructorTestClass.cs" />

Src/Newtonsoft.Json.Tests/Newtonsoft.Json.Tests.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,7 @@
110110
<Compile Include="Linq\ComponentModel\JTypeDescriptionProviderTests.cs" />
111111
<Compile Include="Linq\ComponentModel\JTypeDescriptorTests.cs" />
112112
<Compile Include="Serialization\ConstructorHandlingTests.cs" />
113+
<Compile Include="TestObjects\PersonError.cs" />
113114
<Compile Include="TestObjects\PrivateConstructorTestClass.cs" />
114115
<Compile Include="TestObjects\PrivateConstructorWithPublicParametizedConstructorTestClass.cs" />
115116
<Compile Include="TestObjects\Content.cs" />

0 commit comments

Comments
 (0)