-Documentation

-Added Path to JsonWriterException
This commit is contained in:
James Newton-King
2012-05-07 23:16:24 +12:00
parent a8f4be59ab
commit d815dc7749
22 changed files with 299 additions and 124 deletions
+10 -9
View File
@@ -16,13 +16,16 @@
<span style="color: DarkGray"> </span>
<p>DateTimes in JSON are hard.</p>
<p>
The problem comes from the <a href="http://www.ietf.org/rfc/rfc4627.txt" target="_blank">JSON spec</a> itself, there is no literal syntax for dates in JSON. The spec has objects, arrays, strings, integers and floats, but it defines no standard for what a date looks like.</p>
The problem comes from the <a href="http://www.ietf.org/rfc/rfc4627.txt" target="_blank">JSON spec</a> itself: there is no literal syntax for dates in JSON. The spec has objects, arrays, strings, integers and floats, but it defines no standard for what a date looks like.</p>
<p>The default format used by <a href="http://james.newtonking.com/projects/json-net.aspx" target="_blank">Json.NET</a>
is the ISO 8601 standard: 2012-03-19T07:22Z. You can read more about it <a href="http://en.wikipedia.org/wiki/ISO_8601" target="_blank">here</a>.</p>
<p>Prior to Json.NET 4.5 dates were written using the Microsoft format:
&quot;\/Date(1198908717056)\/&quot;. If you want to use this format, or you want to
maintain compatibility with Microsoft JSON serializers or older versions of
Json.NET then change the DateFormatHandling setting to MicrosoftDateFormat.</p>
Json.NET then change the <a href="html/T_Newtonsoft_Json_DateFormatHandling.htm">DateFormatHandling</a> setting to MicrosoftDateFormat.</p>
<p>Json.NET also has the <a href="html/T_Newtonsoft_Json_DateTimeZoneHandling.htm">DateTimeZoneHandling</a> setting. This can be used to convert
DateTime&#39;s kind when serializing, e.g. set DateTimeZoneHandling to Utc to
serialize all DateTimes as UTC dates.</p>
<h3>DateTime JsonConverters</h3>
<p>With no standard for dates in JSON, the number of possible different formats when interoping with other systems is endless. Fortunately Json.NET has a solution to deal with reading and writing custom dates: JsonConverters. A JsonConverter is used to override how a type is serialized.</p>
@@ -49,16 +52,16 @@
<pre style="margin: 0px;">&nbsp; };</pre>
<pre style="margin: 0px;">&nbsp;</pre>
<pre style="margin: 0px;">&nbsp; <span style="color: green;">// Default as of Json.NET 4.5</span></pre>
<pre style="margin: 0px;">&nbsp; <span style="color: green;">// default as of Json.NET 4.5</span></pre>
<pre style="margin: 0px;">&nbsp; <span style="color: blue;">string</span> isoJson = <span style="color: rgb(43, 145, 175);">JsonConvert</span>.SerializeObject(entry);</pre>
<pre style="margin: 0px;">&nbsp; <span style="color: green;">// {"Details":"Application started.","LogDate":"2009-02-15T00:00:00Z"}</span></pre>
<pre style="margin: 0px;">&nbsp;</pre>
<pre style="margin: 0px;">&nbsp; <span style="color: rgb(43, 145, 175);">JsonSerializerSettings</span> settingsWithMicrosoftDateFormat = <span style="color: blue;">new</span> <span style="color: rgb(43, 145, 175);">JsonSerializerSettings</span></pre>
<pre style="margin: 0px;">&nbsp; <span style="color: rgb(43, 145, 175);">JsonSerializerSettings</span> microsoftDateFormatSettings = <span style="color: blue;">new</span> <span style="color: rgb(43, 145, 175);">JsonSerializerSettings</span></pre>
<pre style="margin: 0px;">&nbsp; {</pre>
<pre style="margin: 0px;">&nbsp;&nbsp;&nbsp; DateFormatHandling = <span style="color: rgb(43, 145, 175);">DateFormatHandling</span>.MicrosoftDateFormat</pre>
<pre style="margin: 0px;">&nbsp; };</pre>
<pre style="margin: 0px;">&nbsp; <span style="color: blue;">string</span> microsoftJson = <span style="color: rgb(43, 145, 175);">JsonConvert</span>.SerializeObject(entry, settingsWithMicrosoftDateFormat);</pre>
<pre style="margin: 0px;">&nbsp; <span style="color: blue;">string</span> microsoftJson = <span style="color: rgb(43, 145, 175);">JsonConvert</span>.SerializeObject(entry, microsoftDateFormatSettings);</pre>
<pre style="margin: 0px;">&nbsp; <span style="color: green;">// {"Details":"Application started.","LogDate":"\/Date(1234656000000)\/"}</span></pre>
<pre style="margin: 0px;">&nbsp;</pre>
@@ -71,7 +74,7 @@
</div>
<p>Simply pass the JsonConverter you wish to use to the Json.NET serializer.</p>
<h4>JavaScriptDateTimeConverter</h4>
<p>The JavaScriptDateTimeConverter class is one of the two DateTime JsonConverters that come with Json.NET. This converter serializes a DateTime as a <a href="https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Global_Objects/Date" target="_blank">JavaScript Date object</a>.</p>
<p>The JavaScriptDateTimeConverter class is one of the two DateTime JsonConverters that come with Json.NET. This converter serializes a DateTime as a <a href="http://msdn.microsoft.com/en-us/library/cd9w2te4.aspx" target="_blank">JavaScript Date object</a>.</p>
<div class="overflowpanel">
<div class="code">
<div style="font-size: 10pt; color: black; font-family: courier new;">
@@ -80,7 +83,7 @@
</div>
</div>
</div>
<p>Technically this is invalid JSON according to the spec but all browsers, and some JSON frameworks including Json.NET, support it. </p>
<p>Technically this is invalid JSON according to the spec but all browsers, and some JSON frameworks, including Json.NET, support it. </p>
<h4>IsoDateTimeConverter</h4>
<p>IsoDateTimeConverter seralizes a DateTime to an <a href="http://en.wikipedia.org/wiki/ISO_8601" target="_blank">ISO 8601</a> formatted string.
Note that since Json.NET 4.5 dates are written using the ISO 8601 format by
@@ -94,8 +97,6 @@
</div>
</div>
<p>The IsoDateTimeConverter class has a property, DateTimeFormat, to further customize the formatted string.</p>
<p>&nbsp;</p>
<p>One final thing to note is all date values returned by Json.NET are in <a href="http://en.wikipedia.org/wiki/Utc" target="_blank">UTC time</a>.</p>
<div id="footer"></div>
+26 -6
View File
@@ -25,8 +25,15 @@
<li><a href="./html/T_Newtonsoft_Json_JsonConverterAttribute.htm">JsonConverterAttribute</a> - Placed on either classes or fields and properties to specify which JsonConverter should be used during serialization.</li>
</ul>
<p>As well as using the built-in Json.NET attributes, Json.NET also looks for the
<a href="http://msdn.microsoft.com/en-us/library/system.runtime.serialization.datacontractattribute.aspx" target="_blank">DataContract</a> and
<a href="http://msdn.microsoft.com/en-us/library/system.runtime.serialization.datacontractattribute.aspx" target="_blank">DataMember</a> attributes when determining how JSON is to be serialized and deserialized. If both are present the Json.NET serialization attributes take precedence.</p>
<a href="http://msdn.microsoft.com/en-us/library/system.serializableattribute.aspx" target="_blank">
Serializable</a> (if IgnoreSerializableAttribute on DefaultContractResolver is
set to false)
<a href="http://msdn.microsoft.com/en-us/library/system.runtime.serialization.datacontractattribute.aspx" target="_blank">DataContract</a>,
<a href="http://msdn.microsoft.com/en-us/library/system.runtime.serialization.datacontractattribute.aspx" target="_blank">DataMember</a>
and
<a href="http://msdn.microsoft.com/en-us/library/system.nonserializedattribute.aspx" target="_blank">
NotSerialized</a> and
attributes when determining how JSON is to be serialized and deserialized. If both are present the Json.NET serialization attributes take precedence.</p>
<div class="overflowpanel"> <div class="code">
@@ -40,7 +47,6 @@
<pre style="margin: 0px;">&nbsp;</pre>
<pre style="margin: 0px;">&nbsp; <span style="color: green;">// "2000-12-15T22:11:03"</span></pre>
<pre style="margin: 0px;">&nbsp; [<span style="color: #2b91af;">JsonProperty</span>]</pre>
<pre style="margin: 0px;">&nbsp; [<span style="color: #2b91af;">JsonConverter</span>(<span style="color: blue;">typeof</span>(<span style="color: #2b91af;">IsoDateTimeConverter</span>))]</pre>
<pre style="margin: 0px;">&nbsp; <span style="color: blue;">public</span> <span style="color: #2b91af;">DateTime</span> BirthDate { <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: green;">// new Date(976918263055)</span></pre>
@@ -48,7 +54,7 @@
<pre style="margin: 0px;">&nbsp; [<span style="color: #2b91af;">JsonConverter</span>(<span style="color: blue;">typeof</span>(<span style="color: #2b91af;">JavaScriptDateTimeConverter</span>))]</pre>
<pre style="margin: 0px;">&nbsp; <span style="color: blue;">public</span> <span style="color: #2b91af;">DateTime</span> LastModified { <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: green;">// not serialized</span></pre>
<pre style="margin: 0px;">&nbsp; <span style="color: green;">// not serialized because mode is opt-in</span></pre>
<pre style="margin: 0px;">&nbsp; <span style="color: blue;">public</span> <span style="color: blue;">string</span> Department { <span style="color: blue;">get</span>; <span style="color: blue;">set</span>; }</pre>
<pre style="margin: 0px;">}</pre>
</div>
@@ -56,11 +62,14 @@
</div></div>
<h5>JsonObjectAttribute</h5>
<p>The MemberSerialization flag on this attribute specifies whether member serialization is opt-in (a member must have the JsonProperty or DataMember attribute to be serialized) or opt-out (everything is serialized by default but can be ignored with the JsonIgnoreAttribute,
Json.NET&#39;s default behavor).</p>
<p>The MemberSerialization flag on this attribute specifies whether member serialization is opt-in (a member must have the JsonProperty or DataMember attribute to be serialized), opt-out (everything is serialized by default but can be ignored with the JsonIgnoreAttribute,
Json.NET&#39;s default behavor) or fields (all public and private fields are
serialized, properties are ignored).</p>
<p>Json.NET serializes .NET classes that implement IEnumerable as an
JSON array populated with the IEnumerable values. Placing the JsonPropertyAttribute overrides this
behavor and forces the serializer to serialize the class's fields and properties.</p>
<p>The DataContractAttribute can be used as substitute for JsonObjectAttribute.
The DataContractAttribute will default member serialization to opt-in.</p>
<h5>JsonArrayAttribute/JsonDictionaryAttribute</h5>
<p>The JsonArrayAttribute and JsonDictionaryAttributes are used to specified
@@ -75,9 +84,14 @@
<li>Includes non-public properties in serialization and deserialization.</li>
<li>Customize type name, reference, null and default value handling for the
property value.</li>
<li>Customize the property&#39;s collection items JsonConverter, type name handing and
reference handling.</li>
</ul>
<p>
The DataMemberAttribute can be used as substitute for JsonPropertyAttribute.</p>
<h5>JsonIgnoreAttribute</h5>
<p>Excludes a field or property from serialization.</p>
<p>The NotSerializedAttribute can be used as substitute for JsonIgnoreAttribute.</p>
<h5>JsonConverterAttribute</h5>
<p>The JsonConverterAttribute specifies which JsonSerializer is used to convert an object.</p>
<p>The attribute can be placed on a class or a member. When placed on a class the JsonConverter
@@ -120,6 +134,12 @@ finally any converters passed to the JsonSerializer.</p>
</div></div>
<p>To apply a JsonConverter to the items in a collection use either
<a href="html/T_Newtonsoft_Json_JsonArrayAttribute.htm">JsonArrayAttribute</a>,
<a href="html/T_Newtonsoft_Json_JsonDictionaryAttribute.htm">
JsonDictionaryAttribute</a> or
<a href="html/T_Newtonsoft_Json_JsonPropertyAttribute.htm">JsonPropertyAttribute</a> and set
the ItemConverterType property to the converter type you want to use.</p>
<div id="footer">
+11 -9
View File
@@ -3,13 +3,7 @@
<title>Serialization Guide</title>
<link href="styles.css" rel="stylesheet" type="text/css" />
<link href="custom.css" rel="stylesheet" type="text/css" />
<style type="text/css">
.style1
{
width: 100%;
}
</style>
</head>
</head>
<body>
<div id="control">
<span class="productTitle">Json.NET - Quick Starts & API Documentation</span><br />
@@ -221,12 +215,20 @@
or the DefaultMembersSearchFlags can be changed on DefaultContractResolver to change
how members are serialized on all types.</p>
<p>
Types can also be serialized using opt-in mode. Only fields that have a JsonPropertyAttribute
Types can also be serialized using opt-in mode. Only
properties and fields that have a JsonPropertyAttribute
or DataMemberAttribute on them will be serialized. Opt-in mode for an object is
specified using the JsonObjectAttribute on the class.
</p>
<p>
Finally types can be serialized using a fields mode. All fields, both public and
private, are serialized and properties are ignored. This can be specified by
setting MemberSerialization.Fields on a type with the JsonObject attribute or by the .NET
<a href="http://msdn.microsoft.com/en-us/library/system.serializableattribute.aspx" target="_blank">
Serializable</a> attribute and setting IgnoreSerializableAttribute on
DefaultContractResolver to false.</p>
<h4>
<strong>IEnumerable, Lists and Arrays</strong></h4>
<strong>IEnumerable, Lists and Arrayss</strong></h4>
<p>
.NET lists (types that inherit from IEnumerable) and .NET arrays are converted to
JSON arrays. Because JSON arrays only support a range of values and not properties,
@@ -378,7 +378,7 @@ namespace Newtonsoft.Json.Tests.Bson
[Test]
public void WriteComment()
{
ExceptionAssert.Throws<JsonWriterException>("Cannot write JSON comment as BSON.",
ExceptionAssert.Throws<JsonWriterException>("Cannot write JSON comment as BSON. Path ''.",
() =>
{
MemoryStream ms = new MemoryStream();
@@ -392,7 +392,7 @@ namespace Newtonsoft.Json.Tests.Bson
[Test]
public void WriteConstructor()
{
ExceptionAssert.Throws<JsonWriterException>("Cannot write JSON constructor as BSON.",
ExceptionAssert.Throws<JsonWriterException>("Cannot write JSON constructor as BSON. Path ''.",
() =>
{
MemoryStream ms = new MemoryStream();
@@ -406,7 +406,7 @@ namespace Newtonsoft.Json.Tests.Bson
[Test]
public void WriteRaw()
{
ExceptionAssert.Throws<JsonWriterException>("Cannot write raw JSON as BSON.",
ExceptionAssert.Throws<JsonWriterException>("Cannot write raw JSON as BSON. Path ''.",
() =>
{
MemoryStream ms = new MemoryStream();
@@ -420,7 +420,7 @@ namespace Newtonsoft.Json.Tests.Bson
[Test]
public void WriteRawValue()
{
ExceptionAssert.Throws<JsonWriterException>("Cannot write raw JSON as BSON.",
ExceptionAssert.Throws<JsonWriterException>("Cannot write raw JSON as BSON. Path ''.",
() =>
{
MemoryStream ms = new MemoryStream();
@@ -652,7 +652,7 @@ namespace Newtonsoft.Json.Tests.Bson
[Test]
public void WriteValueOutsideOfObjectOrArray()
{
ExceptionAssert.Throws<JsonWriterException>("Error writing String value. BSON must start with an Object or Array.",
ExceptionAssert.Throws<JsonWriterException>("Error writing String value. BSON must start with an Object or Array. Path ''.",
() =>
{
MemoryStream stream = new MemoryStream();
@@ -174,8 +174,8 @@ namespace Newtonsoft.Json.Tests
[Test]
public void WriteValueObjectWithUnsupportedValue()
{
ExceptionAssert.Throws<ArgumentException>(
@"Unsupported type: System.Version. Use the JsonSerializer class to get the object's JSON representation.",
ExceptionAssert.Throws<JsonWriterException>(
@"Unsupported type: System.Version. Use the JsonSerializer class to get the object's JSON representation. Path ''.",
() =>
{
StringWriter sw = new StringWriter();
@@ -597,7 +597,7 @@ namespace Newtonsoft.Json.Tests
public void BadWriteEndArray()
{
ExceptionAssert.Throws<JsonWriterException>(
"No token to close.",
"No token to close. Path ''.",
() =>
{
StringBuilder sb = new StringBuilder();
+34 -27
View File
@@ -93,6 +93,7 @@ namespace Newtonsoft.Json.Tests
JsonNet,
JsonNetWithIsoConverter,
JsonNetBinary,
JsonNetLinq,
BinaryFormatter,
JavaScriptSerializer,
DataContractSerializer,
@@ -130,6 +131,7 @@ namespace Newtonsoft.Json.Tests
BenchmarkSerializeMethod(SerializeMethod.JavaScriptSerializer, value);
BenchmarkSerializeMethod(SerializeMethod.DataContractJsonSerializer, value);
BenchmarkSerializeMethod(SerializeMethod.JsonNet, value);
BenchmarkSerializeMethod(SerializeMethod.JsonNetLinq, value);
BenchmarkSerializeMethod(SerializeMethod.JsonNetWithIsoConverter, value);
BenchmarkSerializeMethod(SerializeMethod.JsonNetBinary, value);
}
@@ -428,33 +430,6 @@ namespace Newtonsoft.Json.Tests
};
}
public string SerializeJsonNet(object value)
{
Type type = value.GetType();
Newtonsoft.Json.JsonSerializer json = new Newtonsoft.Json.JsonSerializer();
json.NullValueHandling = NullValueHandling.Ignore;
json.ObjectCreationHandling = Newtonsoft.Json.ObjectCreationHandling.Replace;
json.MissingMemberHandling = Newtonsoft.Json.MissingMemberHandling.Ignore;
json.ReferenceLoopHandling = ReferenceLoopHandling.Ignore;
StringWriter sw = new StringWriter();
Newtonsoft.Json.JsonTextWriter writer = new JsonTextWriter(sw);
writer.Formatting = Formatting.None;
writer.QuoteChar = '"';
json.Serialize(writer, value);
string output = sw.ToString();
writer.Close();
return output;
}
public string SerializeWebExtensions(object value)
{
JavaScriptSerializer ser = new JavaScriptSerializer();
@@ -506,6 +481,38 @@ namespace Newtonsoft.Json.Tests
case SerializeMethod.JsonNetWithIsoConverter:
json = JsonConvert.SerializeObject(value, new IsoDateTimeConverter());
break;
case SerializeMethod.JsonNetLinq:
{
TestClass c = value as TestClass;
if (c != null)
{
JObject o = new JObject(
new JProperty("strings", new JArray(
c.strings
)),
new JProperty("dictionary", new JObject(c.dictionary.Select(d => new JProperty(d.Key, d.Value)))),
new JProperty("Name", c.Name),
new JProperty("Now", c.Now),
new JProperty("BigNumber", c.BigNumber),
new JProperty("Address1", new JObject(
new JProperty("Street", c.Address1.Street),
new JProperty("Phone", c.Address1.Phone),
new JProperty("Entered", c.Address1.Entered))),
new JProperty("Addresses", new JArray(c.Addresses.Select(a =>
new JObject(
new JProperty("Street", a.Street),
new JProperty("Phone", a.Phone),
new JProperty("Entered", a.Entered)))))
);
json = o.ToString(Formatting.None);
}
else
{
json = string.Empty;
}
break;
}
case SerializeMethod.JsonNetBinary:
{
MemoryStream ms = new MemoryStream(Buffer);
@@ -72,5 +72,5 @@ using System.Security;
// by using the '*' as shown below:
[assembly: AssemblyVersion("4.5.0.0")]
#if !PocketPC
[assembly: AssemblyFileVersion("4.5.4.14906")]
[assembly: AssemblyFileVersion("4.5.4.14907")]
#endif
@@ -1197,7 +1197,7 @@ keyword such as type of business.""
public void SerializeRequiredMembersClassNullRequiredValueProperty()
{
ExceptionAssert.Throws<JsonSerializationException>(
"Cannot write a null value for property 'FirstName'. Property requires a value.",
"Cannot write a null value for property 'FirstName'. Property requires a value. Path ''.",
() =>
{
RequiredMembersClass requiredMembersClass = new RequiredMembersClass
@@ -1480,7 +1480,7 @@ keyword such as type of business.""
string classRef = typeof(JsonPropertyWithHandlingValues).FullName;
ExceptionAssert.Throws<JsonSerializationException>(
@"Self referencing loop detected for type '" + classRef + "'.",
"Self referencing loop detected for property 'ReferenceLoopHandlingErrorProperty' with type '" + classRef + "'. Path ''.",
() =>
{
JsonPropertyWithHandlingValues o = new JsonPropertyWithHandlingValues();
@@ -2948,7 +2948,7 @@ To fix this error either change the environment to be fully trusted, change the
{
ExceptionAssert.Throws<JsonSerializationException>(
@"Type 'Newtonsoft.Json.Tests.Serialization.JsonSerializerTest+ISerializableTestObject' implements ISerializable but cannot be serialized using the ISerializable interface because the current application is not fully trusted and ISerializable can expose secure data.
To fix this error either change the environment to be fully trusted, change the application to not deserialize the type, add to JsonObjectAttribute to the type or change the JsonSerializer setting ContractResolver to use a new DefaultContractResolver with IgnoreSerializableInterface set to true.",
To fix this error either change the environment to be fully trusted, change the application to not deserialize the type, add to JsonObjectAttribute to the type or change the JsonSerializer setting ContractResolver to use a new DefaultContractResolver with IgnoreSerializableInterface set to true. Path ''.",
() =>
{
JsonTypeReflector.SetFullyTrusted(false);
@@ -6083,9 +6083,9 @@ Parameter name: value",
}", json);
Assert.AreEqual(3, errors.Count);
Assert.AreEqual("Cannot write a null value for property 'NonAttributeProperty'. Property requires a value.", errors[0]);
Assert.AreEqual("Cannot write a null value for property 'UnsetProperty'. Property requires a value.", errors[1]);
Assert.AreEqual("Cannot write a null value for property 'AlwaysProperty'. Property requires a value.", errors[2]);
Assert.AreEqual("Cannot write a null value for property 'NonAttributeProperty'. Property requires a value. Path ''.", errors[0]);
Assert.AreEqual("Cannot write a null value for property 'UnsetProperty'. Property requires a value. Path ''.", errors[1]);
Assert.AreEqual("Cannot write a null value for property 'AlwaysProperty'. Property requires a value. Path ''.", errors[2]);
}
[Test]
@@ -6133,8 +6133,78 @@ Parameter name: value",
string s = (string) new JsonSerializer().Deserialize(new JsonTextReader(new StringReader("''")));
Assert.AreEqual("", s);
}
#if !(SILVERLIGHT || NETFX_CORE || PORTABLE)
[Test]
public void SerializeAndDeserializeWithAttributes()
{
var testObj = new PersonSerializable() { Name = "John Doe", Age = 28 };
var objDeserialized = this.SerializeAndDeserialize<PersonSerializable>(testObj);
Assert.AreEqual(testObj.Name, objDeserialized.Name);
Assert.AreEqual(0, objDeserialized.Age);
}
private T SerializeAndDeserialize<T>(T obj)
where T : class
{
var json = Serialize(obj);
return Deserialize<T>(json);
}
private string Serialize<T>(T obj)
where T : class
{
var stringWriter = new StringWriter();
var serializer = new Newtonsoft.Json.JsonSerializer();
serializer.ContractResolver = new DefaultContractResolver(false)
{
IgnoreSerializableAttribute = false
};
serializer.Serialize(stringWriter, obj);
return stringWriter.ToString();
}
private T Deserialize<T>(string json)
where T : class
{
var jsonReader = new Newtonsoft.Json.JsonTextReader(new StringReader(json));
var serializer = new Newtonsoft.Json.JsonSerializer();
serializer.ContractResolver = new DefaultContractResolver(false)
{
IgnoreSerializableAttribute = false
};
return serializer.Deserialize(jsonReader, typeof(T)) as T;
}
#endif
}
#if !(SILVERLIGHT || NETFX_CORE || PORTABLE)
[Serializable]
public class PersonSerializable
{
public PersonSerializable()
{ }
private string _name = "";
public string Name
{
get { return _name; }
set { _name = value; }
}
[NonSerialized]
private int _age = 0;
public int Age
{
get { return _age; }
set { _age = value; }
}
}
#endif
public class PropertyItemConverter
{
[JsonProperty(ItemConverterType = typeof(MetroStringConverter))]
@@ -104,7 +104,7 @@ namespace Newtonsoft.Json.Tests.Serialization
circularList.Add(new CircularList { new CircularList { circularList } });
ExceptionAssert.Throws<JsonSerializationException>(
"Self referencing loop detected for type '" + classRef + "'.",
"Self referencing loop detected with type '" + classRef + "'. Path '[2][0]'.",
() =>
{
JsonConvert.SerializeObject(circularList, Formatting.Indented);
@@ -264,7 +264,7 @@ namespace Newtonsoft.Json.Tests.Serialization
circularDictionary.Add("self", circularDictionary);
ExceptionAssert.Throws<JsonSerializationException>(
@"Self referencing loop detected for type '" + classRef + "'.",
@"Self referencing loop detected with type '" + classRef + "'. Path ''.",
() =>
{
JsonConvert.SerializeObject(circularDictionary, Formatting.Indented);
+8 -8
View File
@@ -105,7 +105,7 @@ namespace Newtonsoft.Json.Bson
/// <param name="text">Text to place inside the comment.</param>
public override void WriteComment(string text)
{
throw new JsonWriterException("Cannot write JSON comment as BSON.");
throw JsonWriterException.Create(this, "Cannot write JSON comment as BSON.", null);
}
/// <summary>
@@ -114,7 +114,7 @@ namespace Newtonsoft.Json.Bson
/// <param name="name">The name of the constructor.</param>
public override void WriteStartConstructor(string name)
{
throw new JsonWriterException("Cannot write JSON constructor as BSON.");
throw JsonWriterException.Create(this, "Cannot write JSON constructor as BSON.", null);
}
/// <summary>
@@ -123,7 +123,7 @@ namespace Newtonsoft.Json.Bson
/// <param name="json">The raw JSON to write.</param>
public override void WriteRaw(string json)
{
throw new JsonWriterException("Cannot write raw JSON as BSON.");
throw JsonWriterException.Create(this, "Cannot write raw JSON as BSON.", null);
}
/// <summary>
@@ -132,7 +132,7 @@ namespace Newtonsoft.Json.Bson
/// <param name="json">The raw JSON to write.</param>
public override void WriteRawValue(string json)
{
throw new JsonWriterException("Cannot write raw JSON as BSON.");
throw JsonWriterException.Create(this, "Cannot write raw JSON as BSON.", null);
}
/// <summary>
@@ -210,7 +210,7 @@ namespace Newtonsoft.Json.Bson
else
{
if (token.Type != BsonType.Object && token.Type != BsonType.Array)
throw new JsonWriterException("Error writing {0} value. BSON must start with an Object or Array.".FormatWith(CultureInfo.InvariantCulture, token.Type));
throw JsonWriterException.Create(this, "Error writing {0} value. BSON must start with an Object or Array.".FormatWith(CultureInfo.InvariantCulture, token.Type), null);
_parent = token;
_root = token;
@@ -268,7 +268,7 @@ namespace Newtonsoft.Json.Bson
public override void WriteValue(uint value)
{
if (value > int.MaxValue)
throw new JsonWriterException("Value is too large to fit in a signed 32 bit integer. BSON does not support unsigned values.");
throw JsonWriterException.Create(this, "Value is too large to fit in a signed 32 bit integer. BSON does not support unsigned values.", null);
base.WriteValue(value);
AddValue(value, BsonType.Integer);
@@ -292,7 +292,7 @@ namespace Newtonsoft.Json.Bson
public override void WriteValue(ulong value)
{
if (value > long.MaxValue)
throw new JsonWriterException("Value is too large to fit in a signed 64 bit integer. BSON does not support unsigned values.");
throw JsonWriterException.Create(this, "Value is too large to fit in a signed 64 bit integer. BSON does not support unsigned values.", null);
base.WriteValue(value);
AddValue(value, BsonType.Long);
@@ -470,7 +470,7 @@ namespace Newtonsoft.Json.Bson
ValidationUtils.ArgumentNotNull(value, "value");
if (value.Length != 12)
throw new ArgumentException("An object id must be 12 bytes", "value");
throw JsonWriterException.Create(this, "An object id must be 12 bytes", null);
// hack to update the writer state
AutoComplete(JsonToken.Undefined);
+19
View File
@@ -25,8 +25,10 @@
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Runtime.Serialization;
using System.Text;
using Newtonsoft.Json.Utilities;
namespace Newtonsoft.Json
{
@@ -79,5 +81,22 @@ namespace Newtonsoft.Json
{
}
#endif
internal static string FormatExceptionMessage(IJsonLineInfo lineInfo, string path, string message)
{
message = message.Trim();
if (!message.EndsWith("."))
message += ".";
message += " Path '{0}'".FormatWith(CultureInfo.InvariantCulture, path);
if (lineInfo != null && lineInfo.HasLineInfo())
message += ", line {0}, position {1}".FormatWith(CultureInfo.InvariantCulture, lineInfo.LineNumber, lineInfo.LinePosition);
message += ".";
return message;
}
}
}
+13 -1
View File
@@ -48,7 +48,7 @@ namespace Newtonsoft.Json
internal TypeNameHandling? _itemTypeNameHandling;
/// <summary>
/// Gets the collection's items converter.
/// Gets or sets the converter used when serializing the property's collection items.
/// </summary>
/// <value>The collection's items converter.</value>
public Type ItemConverterType { get; set; }
@@ -141,18 +141,30 @@ namespace Newtonsoft.Json
/// <value>The name of the property.</value>
public string PropertyName { get; set; }
/// <summary>
/// Gets or sets the the reference loop handling used when serializing the property's collection items.
/// </summary>
/// <value>The collection's items reference loop handling.</value>
public ReferenceLoopHandling ItemReferenceLoopHandling
{
get { return _itemReferenceLoopHandling ?? default(ReferenceLoopHandling); }
set { _itemReferenceLoopHandling = value; }
}
/// <summary>
/// Gets or sets the the type name handling used when serializing the property's collection items.
/// </summary>
/// <value>The collection's items type name handling.</value>
public TypeNameHandling ItemTypeNameHandling
{
get { return _itemTypeNameHandling ?? default(TypeNameHandling); }
set { _itemTypeNameHandling = value; }
}
/// <summary>
/// Gets or sets whether this property's collection items are serialized as a reference.
/// </summary>
/// <value>Whether this property's collection items are serialized as a reference.</value>
public bool ItemIsReference
{
get { return _itemIsReference ?? default(bool); }
@@ -44,7 +44,6 @@ namespace Newtonsoft.Json
/// <value>The line number indicating where the error occurred.</value>
public int LineNumber { get; private set; }
/// <summary>
/// Gets the line position indicating where the error occurred.
/// </summary>
@@ -136,22 +135,5 @@ namespace Newtonsoft.Json
return new JsonReaderException(message, ex, path, lineNumber, linePosition);
}
internal static string FormatExceptionMessage(IJsonLineInfo lineInfo, string path, string message)
{
message = message.Trim();
if (!message.EndsWith("."))
message += ".";
message += " Path '{0}'".FormatWith(CultureInfo.InvariantCulture, path);
if (lineInfo != null && lineInfo.HasLineInfo())
message += ", line {0}, position {1}".FormatWith(CultureInfo.InvariantCulture, lineInfo.LineNumber, lineInfo.LinePosition);
message += ".";
return message;
}
}
}
@@ -92,7 +92,7 @@ namespace Newtonsoft.Json
internal static JsonSerializationException Create(IJsonLineInfo lineInfo, string path, string message, Exception ex)
{
message = JsonReaderException.FormatExceptionMessage(lineInfo, path, message);
message = FormatExceptionMessage(lineInfo, path, message);
return new JsonSerializationException(message, ex);
}
+1 -1
View File
@@ -194,7 +194,7 @@ namespace Newtonsoft.Json
_writer.Write(")");
break;
default:
throw new JsonWriterException("Invalid JsonToken: " + token);
throw JsonWriterException.Create(this, "Invalid JsonToken: " + token, null);
}
}
+13 -15
View File
@@ -185,7 +185,7 @@ namespace Newtonsoft.Json
case State.Start:
return WriteState.Start;
default:
throw new JsonWriterException("Invalid state: " + _currentState);
throw JsonWriterException.Create(this, "Invalid state: " + _currentState, null);
}
}
}
@@ -482,17 +482,17 @@ namespace Newtonsoft.Json
private void WriteConstructorDate(JsonReader reader)
{
if (!reader.Read())
throw new JsonWriterException("Unexpected end when reading date constructor.");
throw JsonWriterException.Create(this, "Unexpected end when reading date constructor.", null);
if (reader.TokenType != JsonToken.Integer)
throw new JsonWriterException("Unexpected token when reading date constructor. Expected Integer, got " + reader.TokenType);
throw JsonWriterException.Create(this, "Unexpected token when reading date constructor. Expected Integer, got " + reader.TokenType, null);
long ticks = (long)reader.Value;
DateTime date = JsonConvert.ConvertJavaScriptTicksToDateTime(ticks);
if (!reader.Read())
throw new JsonWriterException("Unexpected end when reading date constructor.");
throw JsonWriterException.Create(this, "Unexpected end when reading date constructor.", null);
if (reader.TokenType != JsonToken.EndConstructor)
throw new JsonWriterException("Unexpected token when reading date constructor. Expected EndConstructor, got " + reader.TokenType);
throw JsonWriterException.Create(this, "Unexpected token when reading date constructor. Expected EndConstructor, got " + reader.TokenType, null);
WriteValue(date);
}
@@ -537,7 +537,7 @@ namespace Newtonsoft.Json
WriteEndConstructor();
break;
default:
throw new JsonWriterException("Unexpected type when writing end: " + type);
throw JsonWriterException.Create(this, "Unexpected type when writing end: " + type, null);
}
}
@@ -560,7 +560,7 @@ namespace Newtonsoft.Json
case JsonToken.EndConstructor:
return JsonContainerType.Constructor;
default:
throw new JsonWriterException("No type for token: " + token);
throw JsonWriterException.Create(this, "No type for token: " + token, null);
}
}
@@ -575,7 +575,7 @@ namespace Newtonsoft.Json
case JsonContainerType.Constructor:
return JsonToken.EndConstructor;
default:
throw new JsonWriterException("No close token for type: " + type);
throw JsonWriterException.Create(this, "No close token for type: " + type, null);
}
}
@@ -606,7 +606,7 @@ namespace Newtonsoft.Json
}
if (levelsToComplete == 0)
throw new JsonWriterException("No token to close.");
throw JsonWriterException.Create(this, "No token to close.", null);
for (int i = 0; i < levelsToComplete; i++)
{
@@ -637,7 +637,7 @@ namespace Newtonsoft.Json
_currentState = State.Start;
break;
default:
throw new JsonWriterException("Unknown JsonType: " + currentLevelType);
throw JsonWriterException.Create(this, "Unknown JsonType: " + currentLevelType, null);
}
}
}
@@ -682,9 +682,7 @@ namespace Newtonsoft.Json
State newState = StateArray[(int)tokenBeingWritten][(int)_currentState];
if (newState == State.Error)
{
throw new JsonWriterException("Token {0} in state {1} would result in an invalid JSON object.".FormatWith(CultureInfo.InvariantCulture, tokenBeingWritten.ToString(), _currentState.ToString()));
}
throw JsonWriterException.Create(this, "Token {0} in state {1} would result in an invalid JSON object.".FormatWith(CultureInfo.InvariantCulture, tokenBeingWritten.ToString(), _currentState.ToString()), null);
if ((_currentState == State.Object || _currentState == State.Array || _currentState == State.Constructor) && tokenBeingWritten != JsonToken.Comment)
{
@@ -1247,7 +1245,7 @@ namespace Newtonsoft.Json
return;
}
throw new ArgumentException("Unsupported type: {0}. Use the JsonSerializer class to get the object's JSON representation.".FormatWith(CultureInfo.InvariantCulture, value.GetType()));
throw JsonWriterException.Create(this, "Unsupported type: {0}. Use the JsonSerializer class to get the object's JSON representation.".FormatWith(CultureInfo.InvariantCulture, value.GetType()), null);
}
#endregion
@@ -1269,7 +1267,7 @@ namespace Newtonsoft.Json
if (ws != null)
{
if (!StringUtils.IsWhiteSpace(ws))
throw new JsonWriterException("Only white space characters should be used.");
throw JsonWriterException.Create(this, "Only white space characters should be used.", null);
}
}
@@ -38,6 +38,12 @@ namespace Newtonsoft.Json
#endif
public class JsonWriterException : JsonException
{
/// <summary>
/// Gets the path to the JSON where the error occurred.
/// </summary>
/// <value>The path to the JSON where the error occurred.</value>
public string Path { get; private set; }
/// <summary>
/// Initializes a new instance of the <see cref="JsonWriterException"/> class.
/// </summary>
@@ -79,5 +85,23 @@ namespace Newtonsoft.Json
{
}
#endif
internal JsonWriterException(string message, Exception innerException, string path)
: base(message, innerException)
{
Path = path;
}
internal static JsonWriterException Create(JsonWriter writer, string message, Exception ex)
{
return Create(writer.ContainerPath, message, ex);
}
internal static JsonWriterException Create(string path, string message, Exception ex)
{
message = FormatExceptionMessage(null, path, message);
return new JsonWriterException(message, ex, path);
}
}
}
@@ -90,7 +90,7 @@ using System.Security;
// by using the '*' as shown below:
[assembly: AssemblyVersion("4.5.0.0")]
#if !PocketPC
[assembly: AssemblyFileVersion("4.5.4.14906")]
[assembly: AssemblyFileVersion("4.5.4.14907")]
#endif
[assembly: CLSCompliant(true)]
@@ -959,9 +959,10 @@ namespace Newtonsoft.Json.Serialization
}
#endif
bool hasJsonIgnoreAttribute = JsonTypeReflector.GetAttribute<JsonIgnoreAttribute>(attributeProvider) != null
bool hasJsonIgnoreAttribute =
JsonTypeReflector.GetAttribute<JsonIgnoreAttribute>(attributeProvider) != null
#if !(SILVERLIGHT || NETFX_CORE || PORTABLE)
|| JsonTypeReflector.GetAttribute<NonSerializedAttribute>(attributeProvider) != null
|| JsonTypeReflector.GetAttribute<NonSerializedAttribute>(attributeProvider) != null
#endif
;
@@ -190,9 +190,28 @@ namespace Newtonsoft.Json.Serialization
return PropertyName;
}
/// <summary>
/// Gets or sets the converter used when serializing the property's collection items.
/// </summary>
/// <value>The collection's items converter.</value>
public JsonConverter ItemConverter { get; set; }
/// <summary>
/// Gets or sets whether this property's collection items are serialized as a reference.
/// </summary>
/// <value>Whether this property's collection items are serialized as a reference.</value>
public bool? ItemIsReference { get; set; }
/// <summary>
/// Gets or sets the the type name handling used when serializing the property's collection items.
/// </summary>
/// <value>The collection's items type name handling.</value>
public TypeNameHandling? ItemTypeNameHandling { get; set; }
/// <summary>
/// Gets or sets the the reference loop handling used when serializing the property's collection items.
/// </summary>
/// <value>The collection's items reference loop handling.</value>
public ReferenceLoopHandling? ItemReferenceLoopHandling { get; set; }
}
}
@@ -208,7 +208,7 @@ namespace Newtonsoft.Json.Serialization
return true;
}
private bool CheckForCircularReference(object value, JsonProperty property, JsonContract contract, JsonContainerContract containerContract, JsonProperty containerProperty)
private bool CheckForCircularReference(JsonWriter writer, object value, JsonProperty property, JsonContract contract, JsonContainerContract containerContract, JsonProperty containerProperty)
{
if (value == null || contract.ContractType == JsonContractType.Primitive || contract.ContractType == JsonContractType.String)
return true;
@@ -229,7 +229,12 @@ namespace Newtonsoft.Json.Serialization
switch (referenceLoopHandling.GetValueOrDefault(Serializer.ReferenceLoopHandling))
{
case ReferenceLoopHandling.Error:
throw new JsonSerializationException("Self referencing loop detected for type '{0}'.".FormatWith(CultureInfo.InvariantCulture, value.GetType()));
string message = "Self referencing loop detected";
if (property != null)
message += " for property '{0}'".FormatWith(CultureInfo.InvariantCulture, property.PropertyName);
message += " with type '{0}'.".FormatWith(CultureInfo.InvariantCulture, value.GetType());
throw JsonSerializationException.Create(null, writer.ContainerPath, message, null);
case ReferenceLoopHandling.Ignore:
return false;
case ReferenceLoopHandling.Serialize:
@@ -336,14 +341,14 @@ namespace Newtonsoft.Json.Serialization
continue;
}
if (!CheckForCircularReference(memberValue, property, memberContract, contract, member))
if (!CheckForCircularReference(writer, memberValue, property, memberContract, contract, member))
continue;
if (memberValue == null)
{
Required resolvedRequired = property._required ?? contract.ItemRequired ?? Required.Default;
if (resolvedRequired == Required.Always)
throw new JsonSerializationException("Cannot write a null value for property '{0}'. Property requires a value.".FormatWith(CultureInfo.InvariantCulture, property.PropertyName));
throw JsonSerializationException.Create(null, writer.ContainerPath, "Cannot write a null value for property '{0}'. Property requires a value.".FormatWith(CultureInfo.InvariantCulture, property.PropertyName), null);
}
writer.WritePropertyName(propertyName);
@@ -412,7 +417,7 @@ namespace Newtonsoft.Json.Serialization
}
else
{
if (!CheckForCircularReference(value, null, contract, collectionContract, containerProperty))
if (!CheckForCircularReference(writer, value, null, contract, collectionContract, containerProperty))
return;
_serializeStack.Add(value);
@@ -449,7 +454,7 @@ namespace Newtonsoft.Json.Serialization
}
else
{
if (CheckForCircularReference(value, null, valueContract, contract, member))
if (CheckForCircularReference(writer, value, null, valueContract, contract, member))
{
SerializeValue(writer, value, valueContract, null, contract, member);
}
@@ -515,8 +520,8 @@ namespace Newtonsoft.Json.Serialization
{
if (!JsonTypeReflector.FullyTrusted)
{
throw new JsonSerializationException(@"Type '{0}' implements ISerializable but cannot be serialized using the ISerializable interface because the current application is not fully trusted and ISerializable can expose secure data.
To fix this error either change the environment to be fully trusted, change the application to not deserialize the type, add to JsonObjectAttribute to the type or change the JsonSerializer setting ContractResolver to use a new DefaultContractResolver with IgnoreSerializableInterface set to true.".FormatWith(CultureInfo.InvariantCulture, value.GetType()));
throw JsonSerializationException.Create(null, writer.ContainerPath, @"Type '{0}' implements ISerializable but cannot be serialized using the ISerializable interface because the current application is not fully trusted and ISerializable can expose secure data.
To fix this error either change the environment to be fully trusted, change the application to not deserialize the type, add to JsonObjectAttribute to the type or change the JsonSerializer setting ContractResolver to use a new DefaultContractResolver with IgnoreSerializableInterface set to true.".FormatWith(CultureInfo.InvariantCulture, value.GetType()), null);
}
contract.InvokeOnSerializing(value, Serializer.Context);
@@ -634,7 +639,7 @@ To fix this error either change the environment to be fully trusted, change the
}
else
{
if (!CheckForCircularReference(value, null, valueContract, contract, member))
if (!CheckForCircularReference(writer, value, null, valueContract, contract, member))
continue;
writer.WritePropertyName(propertyName);
@@ -45,6 +45,21 @@ namespace Newtonsoft.Json.Utilities
public const char LineFeed = '\n';
public const char Tab = '\t';
public static string FormatWith(this string format, IFormatProvider provider, object arg0)
{
return format.FormatWith(provider, new[] { arg0 });
}
public static string FormatWith(this string format, IFormatProvider provider, object arg0, object arg1)
{
return format.FormatWith(provider, new[] { arg0, arg1 });
}
public static string FormatWith(this string format, IFormatProvider provider, object arg0, object arg1, object arg2)
{
return format.FormatWith(provider, new[] { arg0, arg1, arg2 });
}
public static string FormatWith(this string format, IFormatProvider provider, params object[] args)
{
ValidationUtils.ArgumentNotNull(format, "format");