1 #region License
2 // Copyright (c) 2007 James Newton-King
3 //
4 // Permission is hereby granted, free of charge, to any person
5 // obtaining a copy of this software and associated documentation
6 // files (the "Software"), to deal in the Software without
7 // restriction, including without limitation the rights to use,
8 // copy, modify, merge, publish, distribute, sublicense, and/or sell
9 // copies of the Software, and to permit persons to whom the
10 // Software is furnished to do so, subject to the following
11 // conditions:
12 //
13 // The above copyright notice and this permission notice shall be
14 // included in all copies or substantial portions of the Software.
15 //
16 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
18 // OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
20 // HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
21 // WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
22 // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
23 // OTHER DEALINGS IN THE SOFTWARE.
24 #endregion
25 
26 #if !(NET35 || NET20 || PORTABLE || DNXCORE50)
27 using System;
28 using System.Collections.Generic;
29 using System.ComponentModel;
30 using System.Dynamic;
31 using System.IO;
32 using System.Linq;
33 using System.Runtime.Serialization;
34 using System.Text;
35 using Newtonsoft.Json.Converters;
36 using Newtonsoft.Json.Linq;
37 #if NETFX_CORE
38 using Microsoft.VisualStudio.TestPlatform.UnitTestFramework;
39 using TestFixture = Microsoft.VisualStudio.TestPlatform.UnitTestFramework.TestClassAttribute;
40 using Test = Microsoft.VisualStudio.TestPlatform.UnitTestFramework.TestMethodAttribute;
41 #elif DNXCORE50
42 using Xunit;
43 using Test = Xunit.FactAttribute;
44 using Assert = Newtonsoft.Json.Tests.XUnitAssert;
45 #else
46 using NUnit.Framework;
47 #endif
48 using Newtonsoft.Json.Serialization;
49 using Newtonsoft.Json.Tests.TestObjects;
50 using Newtonsoft.Json.Utilities;
51 using System.Globalization;
52 using ErrorEventArgs = Newtonsoft.Json.Serialization.ErrorEventArgs;
53 using File = System.IO.File;
54 
55 namespace Newtonsoft.Json.Tests.Documentation
56 {
57     public static class File
58     {
OpenText(string path)59         public static StreamReader OpenText(string path)
60         {
61             return new StreamReader(new MemoryStream(Encoding.UTF8.GetBytes("{}")));
62         }
63 
CreateText(string path)64         public static StreamWriter CreateText(string path)
65         {
66             return new StreamWriter(new MemoryStream());
67         }
68 
WriteAllText(string path, string contents)69         public static void WriteAllText(string path, string contents)
70         {
71         }
72 
ReadAllText(string path)73         public static string ReadAllText(string path)
74         {
75             return null;
76         }
77     }
78 
79     [TestFixture]
80     public class LinqToJsonTests : TestFixtureBase
81     {
LinqToJsonBasic()82         public void LinqToJsonBasic()
83         {
84             #region LinqToJsonBasic
85             JObject o = JObject.Parse(@"{
86               'CPU': 'Intel',
87               'Drives': [
88                 'DVD read/writer',
89                 '500 gigabyte hard drive'
90               ]
91             }");
92 
93             string cpu = (string)o["CPU"];
94             // Intel
95 
96             string firstDrive = (string)o["Drives"][0];
97             // DVD read/writer
98 
99             IList<string> allDrives = o["Drives"].Select(t => (string)t).ToList();
100             // DVD read/writer
101             // 500 gigabyte hard drive
102             #endregion
103         }
104 
LinqToJsonCreateNormal()105         public void LinqToJsonCreateNormal()
106         {
107             #region LinqToJsonCreateNormal
108             JArray array = new JArray();
109             JValue text = new JValue("Manual text");
110             JValue date = new JValue(new DateTime(2000, 5, 23));
111 
112             array.Add(text);
113             array.Add(date);
114 
115             string json = array.ToString();
116             // [
117             //   "Manual text",
118             //   "2000-05-23T00:00:00"
119             // ]
120             #endregion
121         }
122 
123         public class Post
124         {
125             public string Title { get; set; }
126             public string Description { get; set; }
127             public string Link { get; set; }
128             public IList<string> Categories { get; set; }
129         }
130 
GetPosts()131         private List<Post> GetPosts()
132         {
133             return new List<Post>();
134         }
135 
136         [Test]
LinqToJsonCreateDeclaratively()137         public void LinqToJsonCreateDeclaratively()
138         {
139             #region LinqToJsonCreateDeclaratively
140             List<Post> posts = GetPosts();
141 
142             JObject rss =
143                 new JObject(
144                     new JProperty("channel",
145                         new JObject(
146                             new JProperty("title", "James Newton-King"),
147                             new JProperty("link", "http://james.newtonking.com"),
148                             new JProperty("description", "James Newton-King's blog."),
149                             new JProperty("item",
150                                 new JArray(
151                                     from p in posts
152                                     orderby p.Title
153                                     select new JObject(
154                                         new JProperty("title", p.Title),
155                                         new JProperty("description", p.Description),
156                                         new JProperty("link", p.Link),
157                                         new JProperty("category",
158                                             new JArray(
159                                                 from c in p.Categories
160                                                 select new JValue(c)))))))));
161 
162             Console.WriteLine(rss.ToString());
163 
164             //{
165             //  "channel": {
166             //    "title": "James Newton-King",
167             //    "link": "http://james.newtonking.com",
168             //    "description": "James Newton-King\'s blog.",
169             //    "item": [
170             //      {
171             //        "title": "Json.NET 1.3 + New license + Now on CodePlex",
172             //        "description": "Annoucing the release of Json.NET 1.3, the MIT license and being available on CodePlex",
173             //        "link": "http://james.newtonking.com/projects/json-net.aspx",
174             //        "category": [
175             //          "Json.NET",
176             //          "CodePlex"
177             //        ]
178             //      },
179             //      {
180             //        "title": "LINQ to JSON beta",
181             //        "description": "Annoucing LINQ to JSON",
182             //        "link": "http://james.newtonking.com/projects/json-net.aspx",
183             //        "category": [
184             //          "Json.NET",
185             //          "LINQ"
186             //        ]
187             //      }
188             //    ]
189             //  }
190             //}
191             #endregion
192         }
193 
194         [Test]
LinqToJsonCreateFromObject()195         public void LinqToJsonCreateFromObject()
196         {
197             List<Post> posts = GetPosts();
198 
199             #region LinqToJsonCreateFromObject
200             JObject o = JObject.FromObject(new
201             {
202                 channel = new
203                 {
204                     title = "James Newton-King",
205                     link = "http://james.newtonking.com",
206                     description = "James Newton-King's blog.",
207                     item =
208                         from p in posts
209                         orderby p.Title
210                         select new
211                         {
212                             title = p.Title,
213                             description = p.Description,
214                             link = p.Link,
215                             category = p.Categories
216                         }
217                 }
218             });
219             #endregion
220         }
221 
222         [Test]
LinqToJsonCreateParse()223         public void LinqToJsonCreateParse()
224         {
225             #region LinqToJsonCreateParse
226             string json = @"{
227               CPU: 'Intel',
228               Drives: [
229                 'DVD read/writer',
230                 '500 gigabyte hard drive'
231               ]
232             }";
233 
234             JObject o = JObject.Parse(json);
235             #endregion
236         }
237 
238         [Test]
LinqToJsonCreateParseArray()239         public void LinqToJsonCreateParseArray()
240         {
241             #region LinqToJsonCreateParseArray
242             string json = @"[
243               'Small',
244               'Medium',
245               'Large'
246             ]";
247 
248             JArray a = JArray.Parse(json);
249             #endregion
250         }
251 
252         [Test]
LinqToJsonReadObject()253         public void LinqToJsonReadObject()
254         {
255             #region LinqToJsonReadObject
256             using (StreamReader reader = File.OpenText(@"c:\person.json"))
257             {
258                 JObject o = (JObject)JToken.ReadFrom(new JsonTextReader(reader));
259                 // do stuff
260             }
261             #endregion
262         }
263 
264         [Test]
LinqToJsonSimpleQuerying()265         public void LinqToJsonSimpleQuerying()
266         {
267             #region LinqToJsonSimpleQuerying
268             string json = @"{
269               'channel': {
270                 'title': 'James Newton-King',
271                 'link': 'http://james.newtonking.com',
272                 'description': 'James Newton-King\'s blog.',
273                 'item': [
274                   {
275                     'title': 'Json.NET 1.3 + New license + Now on CodePlex',
276                     'description': 'Annoucing the release of Json.NET 1.3, the MIT license and the source on CodePlex',
277                     'link': 'http://james.newtonking.com/projects/json-net.aspx',
278                     'categories': [
279                       'Json.NET',
280                       'CodePlex'
281                     ]
282                   },
283                   {
284                     'title': 'LINQ to JSON beta',
285                     'description': 'Annoucing LINQ to JSON',
286                     'link': 'http://james.newtonking.com/projects/json-net.aspx',
287                     'categories': [
288                       'Json.NET',
289                       'LINQ'
290                     ]
291                   }
292                 ]
293               }
294             }";
295 
296             JObject rss = JObject.Parse(json);
297 
298             string rssTitle = (string)rss["channel"]["title"];
299             // James Newton-King
300 
301             string itemTitle = (string)rss["channel"]["item"][0]["title"];
302             // Json.NET 1.3 + New license + Now on CodePlex
303 
304             JArray categories = (JArray)rss["channel"]["item"][0]["categories"];
305             // ["Json.NET", "CodePlex"]
306 
307             IList<string> categoriesText = categories.Select(c => (string)c).ToList();
308             // Json.NET
309             // CodePlex
310             #endregion
311         }
312 
313         [Test]
LinqToJsonQuerying()314         public void LinqToJsonQuerying()
315         {
316             JObject rss = JObject.Parse(@"{
317               'channel': {
318                 'title': 'James Newton-King',
319                 'link': 'http://james.newtonking.com',
320                 'description': 'James Newton-King\'s blog.',
321                 'item': [
322                   {
323                     'title': 'Json.NET 1.3 + New license + Now on CodePlex',
324                     'description': 'Annoucing the release of Json.NET 1.3, the MIT license and the source on CodePlex',
325                     'link': 'http://james.newtonking.com/projects/json-net.aspx',
326                     'categories': [
327                       'Json.NET',
328                       'CodePlex'
329                     ]
330                   },
331                   {
332                     'title': 'LINQ to JSON beta',
333                     'description': 'Annoucing LINQ to JSON',
334                     'link': 'http://james.newtonking.com/projects/json-net.aspx',
335                     'categories': [
336                       'Json.NET',
337                       'LINQ'
338                     ]
339                   }
340                 ]
341               }
342             }");
343 
344             #region LinqToJsonQuerying
345             var postTitles =
346                 from p in rss["channel"]["item"]
347                 select (string)p["title"];
348 
349             foreach (var item in postTitles)
350             {
351                 Console.WriteLine(item);
352             }
353 
354             //LINQ to JSON beta
355             //Json.NET 1.3 + New license + Now on CodePlex
356 
357             var categories =
358                 from c in rss["channel"]["item"].SelectMany(i => i["categories"]).Values<string>()
359                 group c by c
360                 into g
361                 orderby g.Count() descending
362                 select new { Category = g.Key, Count = g.Count() };
363 
364             foreach (var c in categories)
365             {
366                 Console.WriteLine(c.Category + " - Count: " + c.Count);
367             }
368 
369             //Json.NET - Count: 2
370             //LINQ - Count: 1
371             //CodePlex - Count: 1
372             #endregion
373 
374             Assert.AreEqual(2, postTitles.Count());
375             Assert.AreEqual(3, categories.Count());
376         }
377 
378         #region LinqToJsonDeserializeObject
379         public class Shortie
380         {
381             public string Original { get; set; }
382             public string Shortened { get; set; }
383             public string Short { get; set; }
384             public ShortieException Error { get; set; }
385         }
386 
387         public class ShortieException
388         {
389             public int Code { get; set; }
390             public string ErrorMessage { get; set; }
391         }
392         #endregion
393 
394         [Test]
LinqToJsonDeserializeExample()395         public void LinqToJsonDeserializeExample()
396         {
397             #region LinqToJsonDeserializeExample
398             string jsonText = @"{
399               'short': {
400                 'original': 'http://www.foo.com/',
401                 'short': 'krehqk',
402                 'error': {
403                   'code': 0,
404                   'msg': 'No action taken'
405                 }
406               }
407             }";
408 
409             JObject json = JObject.Parse(jsonText);
410 
411             Shortie shortie = new Shortie
412             {
413                 Original = (string)json["short"]["original"],
414                 Short = (string)json["short"]["short"],
415                 Error = new ShortieException
416                 {
417                     Code = (int)json["short"]["error"]["code"],
418                     ErrorMessage = (string)json["short"]["error"]["msg"]
419                 }
420             };
421 
422             Console.WriteLine(shortie.Original);
423             // http://www.foo.com/
424 
425             Console.WriteLine(shortie.Error.ErrorMessage);
426             // No action taken
427             #endregion
428 
429             Assert.AreEqual("http://www.foo.com/", shortie.Original);
430             Assert.AreEqual("No action taken", shortie.Error.ErrorMessage);
431         }
432 
433         [Test]
SelectTokenSimple()434         public void SelectTokenSimple()
435         {
436             JObject o = JObject.Parse(@"{
437               'Stores': [
438                 'Lambton Quay',
439                 'Willis Street'
440               ],
441               'Manufacturers': [
442                 {
443                   'Name': 'Acme Co',
444                   'Products': [
445                     {
446                       'Name': 'Anvil',
447                       'Price': 50
448                     }
449                   ]
450                 },
451                 {
452                   'Name': 'Contoso',
453                   'Products': [
454                     {
455                       'Name': 'Elbow Grease',
456                       'Price': 99.95
457                     },
458                     {
459                       'Name': 'Headlight Fluid',
460                       'Price': 4
461                     }
462                   ]
463                 }
464               ]
465             }");
466 
467             #region SelectTokenSimple
468             string name = (string)o.SelectToken("Manufacturers[0].Name");
469             #endregion
470 
471             Assert.AreEqual("Acme Co", name);
472         }
473 
474         [Test]
SelectTokenComplex()475         public void SelectTokenComplex()
476         {
477             #region SelectTokenComplex
478             JObject o = JObject.Parse(@"{
479               'Stores': [
480                 'Lambton Quay',
481                 'Willis Street'
482               ],
483               'Manufacturers': [
484                 {
485                   'Name': 'Acme Co',
486                   'Products': [
487                     {
488                       'Name': 'Anvil',
489                       'Price': 50
490                     }
491                   ]
492                 },
493                 {
494                   'Name': 'Contoso',
495                   'Products': [
496                     {
497                       'Name': 'Elbow Grease',
498                       'Price': 99.95
499                     },
500                     {
501                       'Name': 'Headlight Fluid',
502                       'Price': 4
503                     }
504                   ]
505                 }
506               ]
507             }");
508 
509             string name = (string)o.SelectToken("Manufacturers[0].Name");
510             // Acme Co
511 
512             decimal productPrice = (decimal)o.SelectToken("Manufacturers[0].Products[0].Price");
513             // 50
514 
515             string productName = (string)o.SelectToken("Manufacturers[1].Products[0].Name");
516             // Elbow Grease
517             #endregion
518 
519             Assert.AreEqual("Acme Co", name);
520             Assert.AreEqual(50m, productPrice);
521             Assert.AreEqual("Elbow Grease", productName);
522         }
523 
524         [Test]
SelectTokenLinq()525         public void SelectTokenLinq()
526         {
527             JObject o = JObject.Parse(@"{
528               'Stores': [
529                 'Lambton Quay',
530                 'Willis Street'
531               ],
532               'Manufacturers': [
533                 {
534                   'Name': 'Acme Co',
535                   'Products': [
536                     {
537                       'Name': 'Anvil',
538                       'Price': 50
539                     }
540                   ]
541                 },
542                 {
543                   'Name': 'Contoso',
544                   'Products': [
545                     {
546                       'Name': 'Elbow Grease',
547                       'Price': 99.95
548                     },
549                     {
550                       'Name': 'Headlight Fluid',
551                       'Price': 4
552                     }
553                   ]
554                 }
555               ]
556             }");
557 
558             #region SelectTokenLinq
559             IList<string> storeNames = o.SelectToken("Stores").Select(s => (string)s).ToList();
560             // Lambton Quay
561             // Willis Street
562 
563             IList<string> firstProductNames = o["Manufacturers"].Select(m => (string)m.SelectToken("Products[1].Name")).ToList();
564             // null
565             // Headlight Fluid
566 
567             decimal totalPrice = o["Manufacturers"].Sum(m => (decimal)m.SelectToken("Products[0].Price"));
568             // 149.95
569             #endregion
570 
571             Assert.AreEqual(2, storeNames.Count);
572             Assert.AreEqual(2, firstProductNames.Count);
573             Assert.AreEqual(149.95m, totalPrice);
574         }
575     }
576 }
577 
578 #endif