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