diff --git a/Doc/CreatingLINQtoJSON.aml b/Doc/CreatingLINQtoJSON.aml
new file mode 100644
index 00000000..55fe758e
--- /dev/null
+++ b/Doc/CreatingLINQtoJSON.aml
@@ -0,0 +1,50 @@
+
+
+
+
+ As well as parsing JSON from existing JSON strings, LINQ to JSON objects can be created from scratch to create new JSON structures.
+
+
+
+ Manually Creating JSON
+
+ Setting values and creating objects and arrays one at a time gives you
+ total control but it is more verbose than other options.
+
+
+
+
+
+
+ Creating JSON with LINQ
+
+ Declaratively creating JSON objects using LINQ is a fast way to create JSON from collections of values.
+
+
+
+
+
+
+ Creating JSON from an object
+
+ The last option is to create a JSON object from a non-JSON type using the
+ Overload:Newtonsoft.Json.Linq.JObject.FromObject
+ method. Internally FromObject will use the JsonSerializer to serialize the object to LINQ to JSON objects instead of text.
+
+ The example below is creating a JSON object from an anonymous object but any
+ .NET type can be used with FromObject to create JSON.
+
+
+
+
+
+
+ LINQ to JSON
+ LINQtoJSON.htm
+ _self
+
+
+ Overload:Newtonsoft.Json.Linq.JObject.FromObject
+
+
+
\ No newline at end of file
diff --git a/Doc/JsonSchema.aml b/Doc/JsonSchema.aml
new file mode 100644
index 00000000..feb06ea5
--- /dev/null
+++ b/Doc/JsonSchema.aml
@@ -0,0 +1,62 @@
+
+
+
+
+ Json.NET supports the JSON Schema standard via the T:Newtonsoft.Json.Schema.JsonSchema
+ and T:Newtonsoft.Json.JsonValidatingReader classes. It sits under
+ the N:Newtonsoft.Json.Schema namespace.
+ JSON Schema is used to validate the structure and
+ data types of a piece of JSON, similar to XML Schema for XML. Read more about JSON Schema at
+
+ json-schema.org
+ http://json-schema.org/
+ _blank
+
+
+
+
+ Validating with JSON Schema
+
+The simplest way to check if JSON is valid is to load the JSON into a JObject or JArray and then
+use the M:Newtonsoft.Json.Schema.Extensions.IsValid(Newtonsoft.Json.Linq.JToken,Newtonsoft.Json.Schema.JsonSchema)
+method with the JSON Schema.
+
+
+
+To get validation error messages use the
+M:Newtonsoft.Json.Schema.Extensions.IsValid(Newtonsoft.Json.Linq.JToken,Newtonsoft.Json.Schema.JsonSchema,System.Collections.Generic.IList{System.String}@)
+or
+M:Newtonsoft.Json.Schema.Extensions.Validate(Newtonsoft.Json.Linq.JToken,Newtonsoft.Json.Schema.JsonSchema,Newtonsoft.Json.Schema.ValidationEventHandler)
+overloads.
+
+
+
+Internally IsValid uses T:Newtonsoft.Json.JsonValidatingReader
+to perform the JSON Schema validation. To skip the overhead of loading JSON into a JObject/JArray, validating
+the JSON and then deserializing the JSON into a class, JsonValidatingReader can be used with JsonSerializer to validate JSON while the object is being deserialized.
+
+
+
+
+
+
+
+ Creating JSON Schemas
+
+
+The simplest way to get a T:Newtonsoft.Json.Schema.JsonSchema object is to load it from a string or a file.
+
+
+It is also possible to create JsonSchema objects in code.
+
+
+
+
+
+ T:Newtonsoft.Json.Schema.JsonSchema
+ T:Newtonsoft.Json.JsonValidatingReader
+
+
+
+
\ No newline at end of file
diff --git a/Doc/LINQtoJSON.aml b/Doc/LINQtoJSON.aml
index faba2f45..c4bca7b9 100644
--- a/Doc/LINQtoJSON.aml
+++ b/Doc/LINQtoJSON.aml
@@ -2,86 +2,58 @@
- LINQ to JSON is a programming API for working with JSON objects.
- The API has been designed with LINQ in mind to enable to quick querying
+ LINQ to JSON is an API for working with JSON objects.
+ It has been designed with LINQ in mind to enable to quick querying
and creation of JSON objects. LINQ to JSON sits under the
N:Newtonsoft.Json.Linq
namespace.
+
-
-
- Reading JSON
-
- JSON values can be read from a string use the
- M:Newtonsoft.Json.Linq.JToken.Parse(System.String)
- method.
-
-
-
-
-
-
- Creating JSON
-
-
- There are a number of different options when it comes to creating
- JSON using LINQ to JSON.
-
- The first option is to set values one at a time. You
- have total control but it is more verbose than other options.
-
-
-
- Another option is to create JSON objects declaratively using LINQ.
-
-
-
- Finally you can create a JSON object from a non-JSON type using the
- Overload:Newtonsoft.Json.Linq.JObject.FromObject
- method. The example below is creating a JSON object from an anonymous object but any
- .NET type can be used with FromObject to create JSON.
-
-
-
-
-
- Querying JSON
-
-
- The properties and methods that are the most useful when querying JSON
- objects are
- M:Newtonsoft.Json.Linq.JToken.Children
- and
- P:Newtonsoft.Json.Linq.JToken.Item(System.Object).
-
- Children returns all the children of that object. If it is a
- JObject it will return a collection of properties to work with and if
- it is a JArray you will get a collection of the array's values.
-
- The index property is used to get a specific child, either by
- index position for JSON arrays or property name for JSON objects.
-
-
-
- LINQ to JSON can also be used to manually convert from JSON to a .NET object.
-
-
-
- Manually serializing and deserializing between .NET objects is most useful when
- working with JSON that doesn't closely match your .NET objects.
-
-
-
-
+
+ Topics
+
+ Select a topic below for more information:
+
+
+
+
+ Parsing JSON
+ ParsingLINQtoJSON.htm
+ _self
+
+
+
+
+
+
+ Creating JSON
+ CreatingLINQtoJSON.htm
+ _self
+
+
+
+
+
+
+ Querying JSON with LINQ
+ QueryingLINQtoJSON.htm
+ _self
+
+
+
+
+
+
+ Querying JSON with SelectToken
+ SelectToken.htm
+ _self
+
+
+
+
+
+
-
- Querying LINQ to JSON with SelectToken
- SelectToken.htm
- _self
-
-
T:Newtonsoft.Json.Linq.JObject
T:Newtonsoft.Json.Linq.JArray
T:Newtonsoft.Json.Linq.JValue
diff --git a/Doc/ParsingLINQtoJSON.aml b/Doc/ParsingLINQtoJSON.aml
new file mode 100644
index 00000000..8a2efc11
--- /dev/null
+++ b/Doc/ParsingLINQtoJSON.aml
@@ -0,0 +1,37 @@
+
+
+
+
+ LINQ to JSON has methods available for parsing JSON from a string or loading JSON directly from a file.
+
+
+
+ Parsing JSON text
+
+ JSON values can be read from a string using
+ M:Newtonsoft.Json.Linq.JToken.Parse(System.String).
+
+
+
+
+
+
+
+ Loading JSON from a file
+
+ JSON can also be loaded directly from a file using M:Newtonsoft.Json.Linq.JToken.ReadFrom(Newtonsoft.Json.JsonReader).
+
+
+
+
+
+ LINQ to JSON
+ LINQtoJSON.htm
+ _self
+
+
+ M:Newtonsoft.Json.Linq.JToken.Parse(System.String)
+ M:Newtonsoft.Json.Linq.JToken.ReadFrom(Newtonsoft.Json.JsonReader)
+
+
+
\ No newline at end of file
diff --git a/Doc/QueryingLINQtoJSON.aml b/Doc/QueryingLINQtoJSON.aml
new file mode 100644
index 00000000..bf2f8710
--- /dev/null
+++ b/Doc/QueryingLINQtoJSON.aml
@@ -0,0 +1,60 @@
+
+
+
+
+ LINQ to JSON provides a number of methods for getting data from its objects. The index methods on JObject/JArray let you quickly get data by its property name
+ on an object or index in a collection, while M:Newtonsoft.Json.Linq.JToken.Children lets you get ranges
+ of data as IEnumerable<JToken> to then query using LINQ.
+
+
+
+ Getting values by Property Name or Collection Index
+
+
+ The simplest way to get a value from LINQ to JSON is to use the
+ P:Newtonsoft.Json.Linq.JToken.Item(System.Object) index on
+ JObject/JArray and then cast the returned T:Newtonsoft.Json.Linq.JValue to the type you want.
+
+
+
+
+
+
+
+ Querying with LINQ
+
+ JObject/JArray can also be queried using LINQ. M:Newtonsoft.Json.Linq.JToken.Children
+ returns the children values of a JObject/JArray
+ as an IEnumerable<JToken> that can then be queried with the standard Where/OrderBy/Select LINQ operators.
+
+
+ M:Newtonsoft.Json.Linq.JToken.Children returns all the children of a token. If it is a
+ JObject it will return a collection of properties to work with and if
+ it is a JArray you will get a collection of the array's values.
+
+
+
+
+ LINQ to JSON can also be used to manually convert JSON to a .NET object.
+
+
+
+ Manually serializing and deserializing between .NET objects is useful when you are
+ working with JSON that doesn't closely match your .NET objects.
+
+
+
+
+
+
+ LINQ to JSON
+ LINQtoJSON.htm
+ _self
+
+
+ P:Newtonsoft.Json.Linq.JToken.Item(System.Object)
+ M:Newtonsoft.Json.Linq.JToken.Children
+
+
+
\ No newline at end of file
diff --git a/Doc/doc.content b/Doc/doc.content
index ce0c7870..a7d32cd5 100644
--- a/Doc/doc.content
+++ b/Doc/doc.content
@@ -1,7 +1,7 @@
-
+
@@ -15,9 +15,13 @@
-
-
+
+
+
+
+
-
+
+
\ No newline at end of file
diff --git a/Doc/doc.shfbproj b/Doc/doc.shfbproj
index 4a9ea64c..9be93ec3 100644
--- a/Doc/doc.shfbproj
+++ b/Doc/doc.shfbproj
@@ -140,6 +140,12 @@
+
+
+
+
+
+
diff --git a/Src/Newtonsoft.Json.Tests/Documentation/JsonSchemaTests.cs b/Src/Newtonsoft.Json.Tests/Documentation/JsonSchemaTests.cs
new file mode 100644
index 00000000..09baeb2d
--- /dev/null
+++ b/Src/Newtonsoft.Json.Tests/Documentation/JsonSchemaTests.cs
@@ -0,0 +1,184 @@
+#region License
+// Copyright (c) 2007 James Newton-King
+//
+// Permission is hereby granted, free of charge, to any person
+// obtaining a copy of this software and associated documentation
+// files (the "Software"), to deal in the Software without
+// restriction, including without limitation the rights to use,
+// copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following
+// conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+// OTHER DEALINGS IN THE SOFTWARE.
+#endregion
+
+#if !(NET35 || NET20 || PORTABLE)
+using System;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Dynamic;
+using System.IO;
+using System.Linq;
+using System.Runtime.Serialization;
+using System.Text;
+using Newtonsoft.Json.Converters;
+using Newtonsoft.Json.Linq;
+#if !NETFX_CORE
+using NUnit.Framework;
+#else
+using Microsoft.VisualStudio.TestPlatform.UnitTestFramework;
+using TestFixture = Microsoft.VisualStudio.TestPlatform.UnitTestFramework.TestClassAttribute;
+using Test = Microsoft.VisualStudio.TestPlatform.UnitTestFramework.TestMethodAttribute;
+#endif
+using Newtonsoft.Json.Schema;
+using Newtonsoft.Json.Serialization;
+using Newtonsoft.Json.Tests.TestObjects;
+using Newtonsoft.Json.Utilities;
+using System.Globalization;
+using ErrorEventArgs = Newtonsoft.Json.Serialization.ErrorEventArgs;
+using File = System.IO.File;
+
+namespace Newtonsoft.Json.Tests.Documentation
+{
+ public class JsonSchemaTests
+ {
+ public void IsValidBasic()
+ {
+ #region IsValidBasic
+ string schemaJson = @"{
+ 'description': 'A person',
+ 'type': 'object',
+ 'properties':
+ {
+ 'name': {'type':'string'},
+ 'hobbies': {
+ 'type': 'array',
+ 'items': {'type':'string'}
+ }
+ }
+ }";
+
+ JsonSchema schema = JsonSchema.Parse(schemaJson);
+
+ JObject person = JObject.Parse(@"{
+ 'name': 'James',
+ 'hobbies': ['.NET', 'Blogging', 'Reading', 'Xbox', 'LOLCATS']
+ }");
+
+ bool valid = person.IsValid(schema);
+ // true
+ #endregion
+ }
+
+ public void IsValidMessages()
+ {
+ string schemaJson = @"{
+ 'description': 'A person',
+ 'type': 'object',
+ 'properties':
+ {
+ 'name': {'type':'string'},
+ 'hobbies': {
+ 'type': 'array',
+ 'items': {'type':'string'}
+ }
+ }
+ }";
+
+ #region IsValidMessages
+ JsonSchema schema = JsonSchema.Parse(schemaJson);
+
+ JObject person = JObject.Parse(@"{
+ 'name': null,
+ 'hobbies': ['Invalid content', 0.123456789]
+ }");
+
+ IList messages;
+ bool valid = person.IsValid(schema, out messages);
+ // false
+ // Invalid type. Expected String but got Null. Line 2, position 21.
+ // Invalid type. Expected String but got Float. Line 3, position 51.
+ #endregion
+ }
+
+ public void JsonValidatingReader()
+ {
+ string schemaJson = "{}";
+
+ #region JsonValidatingReader
+ string json = @"{
+ 'name': 'James',
+ 'hobbies': ['.NET', 'Blogging', 'Reading', 'Xbox', 'LOLCATS']
+ }";
+
+ JsonTextReader reader = new JsonTextReader(new StringReader(json));
+
+ JsonValidatingReader validatingReader = new JsonValidatingReader(reader);
+ validatingReader.Schema = JsonSchema.Parse(schemaJson);
+
+ IList messages = new List();
+ validatingReader.ValidationEventHandler += (o, a) => messages.Add(a.Message);
+
+ JsonSerializer serializer = new JsonSerializer();
+ Person p = serializer.Deserialize(validatingReader);
+ #endregion
+ }
+
+ public void LoadJsonSchema()
+ {
+ #region LoadJsonSchema
+ // load from a string
+ JsonSchema schema1 = JsonSchema.Parse(@"{'type':'object'}");
+
+ // load from a file
+ using (TextReader reader = File.OpenText(@"c:\schema\Person.json"))
+ {
+ JsonSchema schema2 = JsonSchema.Read(new JsonTextReader(reader));
+
+ // do stuff
+ }
+ #endregion
+ }
+
+ public void ManuallyCreateJsonSchema()
+ {
+ #region ManuallyCreateJsonSchema
+ JsonSchema schema = new JsonSchema();
+ schema.Type = JsonSchemaType.Object;
+ schema.Properties = new Dictionary
+ {
+ {"name", new JsonSchema {Type = JsonSchemaType.String}},
+ {
+ "hobbies", new JsonSchema
+ {
+ Type = JsonSchemaType.Array,
+ Items = new List { new JsonSchema {Type = JsonSchemaType.String} }
+ }
+ },
+ };
+
+ JObject person = JObject.Parse(@"{
+ 'name': 'James',
+ 'hobbies': ['.NET', 'Blogging', 'Reading', 'Xbox', 'LOLCATS']
+ }");
+
+ bool valid = person.IsValid(schema);
+ // true
+ #endregion
+
+ Assert.IsTrue(valid);
+ }
+ }
+}
+#endif
\ No newline at end of file
diff --git a/Src/Newtonsoft.Json.Tests/Documentation/LinqToJsonTests.cs b/Src/Newtonsoft.Json.Tests/Documentation/LinqToJsonTests.cs
index 75bb7b6d..4ae7b133 100644
--- a/Src/Newtonsoft.Json.Tests/Documentation/LinqToJsonTests.cs
+++ b/Src/Newtonsoft.Json.Tests/Documentation/LinqToJsonTests.cs
@@ -46,11 +46,43 @@ using Newtonsoft.Json.Tests.TestObjects;
using Newtonsoft.Json.Utilities;
using System.Globalization;
using ErrorEventArgs = Newtonsoft.Json.Serialization.ErrorEventArgs;
+using File = System.IO.File;
namespace Newtonsoft.Json.Tests.Documentation
{
+ public static class File
+ {
+ public static StreamReader OpenText(string path)
+ {
+ return null;
+ }
+ }
+
public class LinqToJsonTests
{
+ public void LinqToJsonBasic()
+ {
+ #region LinqToJsonBasic
+ JObject o = JObject.Parse(@"{
+ 'CPU': 'Intel',
+ 'Drives': [
+ 'DVD read/writer',
+ '500 gigabyte hard drive'
+ ]
+ }");
+
+ string cpu = (string)o["CPU"];
+ // Intel
+
+ string firstDrive = (string)o["Drives"][0];
+ // DVD read/writer
+
+ IList allDrives = o["Drives"].Select(t => (string)t).ToList();
+ // DVD read/writer
+ // 500 gigabyte hard drive
+ #endregion
+ }
+
public void LinqToJsonCreateNormal()
{
#region LinqToJsonCreateNormal
@@ -194,6 +226,65 @@ namespace Newtonsoft.Json.Tests.Documentation
#endregion
}
+ public void LinqToJsonReadObject()
+ {
+ #region LinqToJsonReadObject
+ using (StreamReader reader = File.OpenText(@"c:\person.json"))
+ {
+ JObject o = (JObject)JToken.ReadFrom(new JsonTextReader(reader));
+ // do stuff
+ }
+ #endregion
+ }
+
+ public void LinqToJsonSimpleQuerying()
+ {
+ #region LinqToJsonSimpleQuerying
+ string json = @"{
+ 'channel': {
+ 'title': 'James Newton-King',
+ 'link': 'http://james.newtonking.com',
+ 'description': 'James Newton-King's blog.',
+ 'item': [
+ {
+ 'title': 'Json.NET 1.3 + New license + Now on CodePlex',
+ 'description': 'Annoucing the release of Json.NET 1.3, the MIT license and the source being available on CodePlex',
+ 'link': 'http://james.newtonking.com/projects/json-net.aspx',
+ 'categories': [
+ 'Json.NET',
+ 'CodePlex'
+ ]
+ },
+ {
+ 'title': 'LINQ to JSON beta',
+ 'description': 'Annoucing LINQ to JSON',
+ 'link': 'http://james.newtonking.com/projects/json-net.aspx',
+ 'categories': [
+ 'Json.NET',
+ 'LINQ'
+ ]
+ }
+ ]
+ }
+ }";
+
+ JObject rss = JObject.Parse(json);
+
+ string rssTitle = (string)rss["channel"]["title"];
+ // James Newton-King
+
+ string itemTitle = (string)rss["channel"]["item"][0]["title"];
+ // Json.NET 1.3 + New license + Now on CodePlex
+
+ JArray categories = (JArray)rss["channel"]["item"][0]["categories"];
+ // ["Json.NET", "CodePlex"]
+
+ IList categoriesText = categories.Select(c => (string)c).ToList();
+ // Json.NET
+ // CodePlex
+ #endregion
+ }
+
public void LinqToJsonQuerying()
{
JObject rss = new JObject();
diff --git a/Src/Newtonsoft.Json.Tests/Documentation/SerializationTests.cs b/Src/Newtonsoft.Json.Tests/Documentation/SerializationTests.cs
index 2964b6e7..2b82d61f 100644
--- a/Src/Newtonsoft.Json.Tests/Documentation/SerializationTests.cs
+++ b/Src/Newtonsoft.Json.Tests/Documentation/SerializationTests.cs
@@ -882,6 +882,30 @@ namespace Newtonsoft.Json.Tests.Documentation
// Url = http://www.imdb.com/name/nm0385296/
#endregion
}
+
+ public void SerializeMultidimensionalArrayExample()
+ {
+ string[,] famousCouples = new string[,]
+ {
+ {"Adam", "Eve"},
+ {"Bonnie", "Clyde"},
+ {"Donald", "Daisy"},
+ {"Han", "Leia"}
+ };
+
+ string json = JsonConvert.SerializeObject(famousCouples, Formatting.Indented);
+ // [
+ // ["Adam", "Eve"],
+ // ["Bonnie", "Clyde"],
+ // ["Donald", "Daisy"],
+ // ["Han", "Leia"]
+ // ]
+
+ string[,] deserialized = JsonConvert.DeserializeObject(json);
+
+ Console.WriteLine(deserialized[3, 0] + ", " + deserialized[3, 1]);
+ // Han, Leia
+ }
}
}
#endif
\ No newline at end of file
diff --git a/Src/Newtonsoft.Json.Tests/Newtonsoft.Json.Tests.csproj b/Src/Newtonsoft.Json.Tests/Newtonsoft.Json.Tests.csproj
index 90f04df7..6885929d 100644
--- a/Src/Newtonsoft.Json.Tests/Newtonsoft.Json.Tests.csproj
+++ b/Src/Newtonsoft.Json.Tests/Newtonsoft.Json.Tests.csproj
@@ -117,6 +117,7 @@
+
diff --git a/Src/Newtonsoft.Json.Tests/PerformanceTests.cs b/Src/Newtonsoft.Json.Tests/PerformanceTests.cs
index d692480f..9db01802 100644
--- a/Src/Newtonsoft.Json.Tests/PerformanceTests.cs
+++ b/Src/Newtonsoft.Json.Tests/PerformanceTests.cs
@@ -768,6 +768,27 @@ namespace Newtonsoft.Json.Tests
BenchmarkSerializeMethod(SerializeMethod.JsonNet, s);
}
+ [Test]
+ public void ParseJObject()
+ {
+ Stopwatch timer = new Stopwatch();
+ timer.Start();
+ for (int i = 0; i < 100000; i++)
+ {
+ JObject o = JObject.Parse(@"{
+ ""CPU"": ""Intel"",
+ ""Drives"": [
+ ""DVD read/writer"",
+ ""500 gigabyte hard drive""
+ ]
+}");
+ }
+ timer.Stop();
+
+ string linq = timer.Elapsed.TotalSeconds.ToString();
+ Console.WriteLine(linq);
+ }
+
[Test]
public void JObjectToString()
{
@@ -778,7 +799,7 @@ namespace Newtonsoft.Json.Tests
for (int i = 0; i < Iterations; i++)
{
test["dummy"] = new JValue(i);
- Encoding.UTF8.GetBytes(test.ToString(Formatting.None));
+ test.ToString(Formatting.None);
}
return null;
}, "JObject.ToString");