1 // Copyright (c) Microsoft Corporation. All rights reserved. See License.txt in the project root for license information. 2 3 using System.Collections; 4 using System.Collections.Generic; 5 using System.ComponentModel; 6 using System.Diagnostics.CodeAnalysis; 7 #if FEATURE_DYNAMIC 8 using System.Dynamic; 9 #endif 10 using System.Globalization; 11 using System.IO; 12 using System.Linq.Expressions; 13 using System.Runtime.Serialization; 14 using System.Runtime.Serialization.Json; 15 using System.Text; 16 using System.Xml; 17 18 namespace System.Json 19 { 20 /// <summary> 21 /// This is the base class for JavaScript Object Notation (JSON) common language runtime (CLR) types. 22 /// </summary> 23 [SuppressMessage("Microsoft.Naming", "CA1710:IdentifiersShouldHaveCorrectSuffix", 24 Justification = "JsonValue is by definition either a collection or a single object.")] 25 [DataContract] 26 #if FEATURE_DYNAMIC 27 public class JsonValue : IEnumerable<KeyValuePair<string, JsonValue>>, IDynamicMetaObjectProvider 28 #else 29 public class JsonValue : IEnumerable<KeyValuePair<string, JsonValue>> 30 #endif 31 { 32 private static JsonValue defaultInstance = new JsonValue(); 33 private int changingListenersCount; 34 private int changedListenersCount; 35 JsonValue()36 internal JsonValue() 37 { 38 } 39 40 /// <summary> 41 /// Raised when this <see cref="System.Json.JsonValue"/> or any of its members have changed. 42 /// </summary> 43 /// <remarks><p>Events are raised when elements are added or removed to <see cref="System.Json.JsonValue"/> 44 /// instances. It applies to both complex descendants of <see cref="System.Json.JsonValue"/>: <see cref="System.Json.JsonArray"/> 45 /// and <see cref="System.Json.JsonObject"/>.</p> 46 /// <p>You should be careful when modifying a <see cref="System.Json.JsonValue"/> tree within one of these events, 47 /// because doing this might lead to unexpected results. For example, if you receive a Changing event, and while 48 /// the event is being processed you remove the node from the tree, you might not receive the Changed event. When 49 /// an event is being processed, it is valid to modify a tree other than the one that contains the node that is 50 /// receiving the event; it is even valid to modify the same tree provided the modifications do not affect the 51 /// specific nodes on which the event was raised. However, if you modify the area of the tree that contains the 52 /// node receiving the event, the events that you receive and the impact to the tree are undefined.</p></remarks> 53 public event EventHandler<JsonValueChangeEventArgs> Changed 54 { 55 add 56 { 57 changedListenersCount++; 58 OnChanged += value; 59 } 60 61 remove 62 { 63 changedListenersCount--; 64 OnChanged -= value; 65 } 66 } 67 68 /// <summary> 69 /// Raised when this <see cref="System.Json.JsonValue"/> or any of its members are about to be changed. 70 /// </summary> 71 /// <remarks><p>Events are raised when elements are added or removed to <see cref="System.Json.JsonValue"/> 72 /// instances. It applies to both complex descendants of <see cref="System.Json.JsonValue"/>: <see cref="System.Json.JsonArray"/> 73 /// and <see cref="System.Json.JsonObject"/>.</p> 74 /// <p>You should be careful when modifying a <see cref="System.Json.JsonValue"/> tree within one of these events, 75 /// because doing this might lead to unexpected results. For example, if you receive a Changing event, and while 76 /// the event is being processed you remove the node from the tree, you might not receive the Changed event. When 77 /// an event is being processed, it is valid to modify a tree other than the one that contains the node that is 78 /// receiving the event; it is even valid to modify the same tree provided the modifications do not affect the 79 /// specific nodes on which the event was raised. However, if you modify the area of the tree that contains the 80 /// node receiving the event, the events that you receive and the impact to the tree are undefined.</p></remarks> 81 public event EventHandler<JsonValueChangeEventArgs> Changing 82 { 83 add 84 { 85 changingListenersCount++; 86 OnChanging += value; 87 } 88 89 remove 90 { 91 changingListenersCount--; 92 OnChanging -= value; 93 } 94 } 95 96 private event EventHandler<JsonValueChangeEventArgs> OnChanged; 97 private event EventHandler<JsonValueChangeEventArgs> OnChanging; 98 99 /// <summary> 100 /// Gets the JSON CLR type represented by this instance. 101 /// </summary> 102 public virtual JsonType JsonType 103 { 104 get { return JsonType.Default; } 105 } 106 107 /// <summary> 108 /// Gets the number of items in this object. 109 /// </summary> 110 public virtual int Count 111 { 112 get { return 0; } 113 } 114 115 /// <summary> 116 /// Gets the number of listeners to the <see cref="Changing"/> event for this instance. 117 /// </summary> 118 protected int ChangingListenersCount 119 { 120 get { return changingListenersCount; } 121 } 122 123 /// <summary> 124 /// Gets the number of listeners to the <see cref="Changed"/> event for this instance. 125 /// </summary> 126 protected int ChangedListenersCount 127 { 128 get { return changedListenersCount; } 129 } 130 131 /// <summary> 132 /// Gets the default JsonValue instance. 133 /// This instance enables safe-chaining of JsonValue operations and resolves to 'null' 134 /// when this instance is used as dynamic, mapping to the JavaScript 'null' value. 135 /// </summary> 136 private static JsonValue DefaultInstance 137 { 138 get { return defaultInstance; } 139 } 140 141 /// <summary> 142 /// This indexer is not supported for this base class and throws an exception. 143 /// </summary> 144 /// <param name="key">The key of the element to get or set.</param> 145 /// <returns><see cref="System.Json.JsonValue"/>.</returns> 146 /// <remarks>The exception thrown is the <see cref="System.InvalidOperationException"/>. 147 /// This method is overloaded in the implementation of the <see cref="System.Json.JsonObject"/> 148 /// class, which inherits from this class.</remarks> 149 public virtual JsonValue this[string key] 150 { 151 get { throw new InvalidOperationException(RS.Format(Properties.Resources.IndexerNotSupportedOnJsonType, typeof(string), JsonType)); } 152 153 set { throw new InvalidOperationException(RS.Format(Properties.Resources.IndexerNotSupportedOnJsonType, typeof(string), JsonType)); } 154 } 155 156 /// <summary> 157 /// This indexer is not supported for this base class and throws an exception. 158 /// </summary> 159 /// <param name="index">The zero-based index of the element to get or set.</param> 160 /// <returns><see cref="System.Json.JsonValue"/>.</returns> 161 /// <remarks>The exception thrown is the <see cref="System.InvalidOperationException"/>. 162 /// This method is overloaded in the implementation of the <see cref="System.Json.JsonArray"/> 163 /// class, which inherits from this class.</remarks> 164 public virtual JsonValue this[int index] 165 { 166 get { throw new InvalidOperationException(RS.Format(Properties.Resources.IndexerNotSupportedOnJsonType, typeof(int), JsonType)); } 167 168 set { throw new InvalidOperationException(RS.Format(Properties.Resources.IndexerNotSupportedOnJsonType, typeof(int), JsonType)); } 169 } 170 171 /// <summary> 172 /// Deserializes text-based JSON into a JSON CLR type. 173 /// </summary> 174 /// <param name="json">The text-based JSON to be parsed into a JSON CLR type.</param> 175 /// <returns>The <see cref="System.Json.JsonValue"/> object that represents the parsed 176 /// text-based JSON as a CLR type.</returns> 177 /// <exception cref="System.ArgumentException">The length of jsonString is zero.</exception> 178 /// <exception cref="System.ArgumentNullException">jsonString is null.</exception> 179 /// <remarks>The result will be an instance of either <see cref="System.Json.JsonArray"/>, 180 /// <see cref="System.Json.JsonObject"/> or <see cref="System.Json.JsonPrimitive"/>, 181 /// depending on the text-based JSON supplied to the method.</remarks> Parse(string json)182 public static JsonValue Parse(string json) 183 { 184 return JXmlToJsonValueConverter.JXMLToJsonValue(json); 185 } 186 187 /// <summary> 188 /// Deserializes text-based JSON from a text reader into a JSON CLR type. 189 /// </summary> 190 /// <param name="textReader">A <see cref="System.IO.TextReader"/> over text-based JSON content.</param> 191 /// <returns>The <see cref="System.Json.JsonValue"/> object that represents the parsed 192 /// text-based JSON as a CLR type.</returns> 193 /// <exception cref="System.ArgumentNullException">textReader is null.</exception> 194 /// <remarks>The result will be an instance of either <see cref="System.Json.JsonArray"/>, 195 /// <see cref="System.Json.JsonObject"/> or <see cref="System.Json.JsonPrimitive"/>, 196 /// depending on the text-based JSON supplied to the method.</remarks> Load(TextReader textReader)197 public static JsonValue Load(TextReader textReader) 198 { 199 if (textReader == null) 200 { 201 throw new ArgumentNullException("textReader"); 202 } 203 204 return JsonValue.Parse(textReader.ReadToEnd()); 205 } 206 207 /// <summary> 208 /// Deserializes text-based JSON from a stream into a JSON CLR type. 209 /// </summary> 210 /// <param name="stream">A <see cref="System.IO.Stream"/> that contains text-based JSON content.</param> 211 /// <returns>The <see cref="System.Json.JsonValue"/> object that represents the parsed 212 /// text-based JSON as a CLR type.</returns> 213 /// <exception cref="System.ArgumentNullException">stream is null.</exception> 214 /// <remarks>The result will be an instance of either <see cref="System.Json.JsonArray"/>, 215 /// <see cref="System.Json.JsonObject"/> or <see cref="System.Json.JsonPrimitive"/>, 216 /// depending on the text-based JSON supplied to the method.</remarks> Load(Stream stream)217 public static JsonValue Load(Stream stream) 218 { 219 return JXmlToJsonValueConverter.JXMLToJsonValue(stream); 220 } 221 222 /// <summary> 223 /// Performs a cast operation from a <see cref="JsonValue"/> instance into the specified type parameter./> 224 /// </summary> 225 /// <typeparam name="T">The type to cast the instance to.</typeparam> 226 /// <param name="value">The <see cref="System.Json.JsonValue"/> instance.</param> 227 /// <returns>An object of type T initialized with the <see cref="System.Json.JsonValue"/> value specified.</returns> 228 /// <remarks>This method is to support the framework and is not intended to be used externally, use explicit type cast instead.</remarks> 229 [EditorBrowsable(EditorBrowsableState.Never)] 230 [SuppressMessage("Microsoft.Design", "CA1004:GenericMethodsShouldProvideTypeParameter", 231 Justification = "The generic parameter is used to specify the output type")] CastValue(JsonValue value)232 public static T CastValue<T>(JsonValue value) 233 { 234 Type typeofT = typeof(T); 235 236 if ((value != null && typeofT.IsAssignableFrom(value.GetType())) || typeofT == typeof(object)) 237 { 238 return (T)(object)value; 239 } 240 241 if (value == null || value.JsonType == JsonType.Default) 242 { 243 if (typeofT.IsValueType) 244 { 245 throw new InvalidCastException(RS.Format(Properties.Resources.InvalidCastNonNullable, typeofT.FullName)); 246 } 247 else 248 { 249 return default(T); 250 } 251 } 252 253 try 254 { 255 return value.ReadAs<T>(); 256 } 257 catch (Exception ex) 258 { 259 if (ex is FormatException || ex is NotSupportedException || ex is InvalidCastException) 260 { 261 throw new InvalidCastException(RS.Format(Properties.Resources.CannotCastJsonValue, value.GetType().FullName, typeofT.FullName), ex); 262 } 263 264 throw; 265 } 266 } 267 268 /// <summary> 269 /// Returns an enumerator which iterates through the values in this object. 270 /// </summary> 271 /// <returns>An enumerator which which iterates through the values in this object.</returns> 272 /// <remarks>The enumerator returned by this class is empty; subclasses will override this method to return appropriate enumerators for themselves.</remarks> GetEnumerator()273 public IEnumerator<KeyValuePair<string, JsonValue>> GetEnumerator() 274 { 275 return GetKeyValuePairEnumerator(); 276 } 277 278 /// <summary> 279 /// Returns an enumerator which iterates through the values in this object. 280 /// </summary> 281 /// <returns>An <see cref="System.Collections.IEnumerator"/> which iterates through the values in this object.</returns> 282 /// <remarks>The enumerator returned by this class is empty; subclasses will override this method to return appropriate enumerators for themselves.</remarks> IEnumerable.GetEnumerator()283 IEnumerator IEnumerable.GetEnumerator() 284 { 285 return GetKeyValuePairEnumerator(); 286 } 287 288 #if FEATURE_DYNAMIC 289 /// <summary> 290 /// Gets this instance as a <code>dynamic</code> object. 291 /// </summary> 292 /// <returns>This instance as <code>dynamic</code>.</returns> AsDynamic()293 public dynamic AsDynamic() 294 { 295 return this; 296 } 297 #endif 298 299 /// <summary> 300 /// Attempts to convert this <see cref="System.Json.JsonValue"/> instance into the type T. 301 /// </summary> 302 /// <typeparam name="T">The type to which the conversion is being performed.</typeparam> 303 /// <param name="valueOfT">An instance of T initialized with this instance, or the default value of T if the conversion cannot be performed.</param> 304 /// <returns>true if this <see cref="System.Json.JsonValue"/> instance can be read as type T; otherwise, false.</returns> TryReadAs(out T valueOfT)305 public bool TryReadAs<T>(out T valueOfT) 306 { 307 object value; 308 if (TryReadAs(typeof(T), out value)) 309 { 310 valueOfT = (T)value; 311 return true; 312 } 313 314 valueOfT = default(T); 315 return false; 316 } 317 318 /// <summary> 319 /// Attempts to convert this <see cref="System.Json.JsonValue"/> instance into the type T. 320 /// </summary> 321 /// <typeparam name="T">The type to which the conversion is being performed.</typeparam> 322 /// <returns>An instance of T initialized with the value from the conversion of this instance.</returns> 323 /// <exception cref="System.NotSupportedException">If this <see cref="System.Json.JsonValue"/> value cannot be converted into the type T.</exception> 324 [SuppressMessage("Microsoft.Design", "CA1004:GenericMethodsShouldProvideTypeParameter", 325 Justification = "The generic parameter is used to specify the output type")] ReadAs()326 public T ReadAs<T>() 327 { 328 return (T)ReadAs(typeof(T)); 329 } 330 331 /// <summary> 332 /// Attempts to convert this <see cref="System.Json.JsonValue"/> instance into the type T. 333 /// </summary> 334 /// <typeparam name="T">The type to which the conversion is being performed.</typeparam> 335 /// <param name="fallback">The fallback value to be returned if the conversion cannot be made.</param> 336 /// <returns>An instance of T initialized with the value from the conversion of this instance, or the specified fallback value if the conversion cannot be made.</returns> ReadAs(T fallback)337 public T ReadAs<T>(T fallback) 338 { 339 return (T)ReadAs(typeof(T), fallback); 340 } 341 342 /// <summary> 343 /// Attempts to convert this <see cref="System.Json.JsonValue"/> instance to an instance of the specified type. 344 /// </summary> 345 /// <param name="type">The type to which the conversion is being performed.</param> 346 /// <param name="fallback">The fallback value to be returned if the conversion cannot be made.</param> 347 /// <returns>An instance of the specified type initialized with the value from the conversion of this instance, or the specified fallback value if the conversion cannot be made.</returns> ReadAs(Type type, object fallback)348 public object ReadAs(Type type, object fallback) 349 { 350 if (type == null) 351 { 352 throw new ArgumentNullException("type"); 353 } 354 355 object result; 356 if (JsonType != JsonType.Default && TryReadAs(type, out result)) 357 { 358 return result; 359 } 360 else 361 { 362 return fallback; 363 } 364 } 365 366 /// <summary> 367 /// Attempts to convert this <see cref="System.Json.JsonValue"/> instance into an instance of the specified type. 368 /// </summary> 369 /// <param name="type">The type to which the conversion is being performed.</param> 370 /// <returns>An instance of the specified type initialized with the value from the conversion of this instance.</returns> 371 /// <exception cref="System.NotSupportedException">If this <see cref="System.Json.JsonValue"/> value cannot be converted into the type T.</exception> ReadAs(Type type)372 public virtual object ReadAs(Type type) 373 { 374 if (type == null) 375 { 376 throw new ArgumentNullException("type"); 377 } 378 379 object result; 380 if (TryReadAs(type, out result)) 381 { 382 return result; 383 } 384 385 throw new NotSupportedException(RS.Format(Properties.Resources.CannotReadAsType, GetType().FullName, type.FullName)); 386 } 387 388 /// <summary> 389 /// Attempts to convert this <see cref="System.Json.JsonValue"/> instance into an instance of the specified type. 390 /// </summary> 391 /// <param name="type">The type to which the conversion is being performed.</param> 392 /// <param name="value">An object to be initialized with this instance or null if the conversion cannot be performed.</param> 393 /// <returns>true if this <see cref="System.Json.JsonValue"/> instance can be read as the specified type; otherwise, false.</returns> 394 [SuppressMessage("Microsoft.Design", "CA1007:UseGenericsWhereAppropriate", 395 Justification = "This is the non-generic version of the method.")] TryReadAs(Type type, out object value)396 public virtual bool TryReadAs(Type type, out object value) 397 { 398 if (type == null) 399 { 400 throw new ArgumentNullException("type"); 401 } 402 403 if (type.IsAssignableFrom(GetType()) || type == typeof(object)) 404 { 405 value = this; 406 return true; 407 } 408 409 value = null; 410 return false; 411 } 412 413 /// <summary> 414 /// Writes this <see cref="System.Json.JsonValue"/> instance to a <see cref="System.IO.Stream"/>. 415 /// </summary> 416 /// <param name="stream">Stream to which to write text-based JSON.</param> Save(Stream stream)417 public void Save(Stream stream) 418 { 419 if (JsonType == JsonType.Default) 420 { 421 throw new InvalidOperationException(Properties.Resources.UseOfDefaultNotAllowed); 422 } 423 424 if (stream == null) 425 { 426 throw new ArgumentNullException("stream"); 427 } 428 429 using (XmlDictionaryWriter jsonWriter = JsonReaderWriterFactory.CreateJsonWriter(stream, Encoding.UTF8, false)) 430 { 431 jsonWriter.WriteStartElement(JXmlToJsonValueConverter.RootElementName); 432 Save(jsonWriter); 433 jsonWriter.WriteEndElement(); 434 } 435 } 436 437 /// <summary> 438 /// Writes <see cref="System.Json.JsonValue"/> instance to a <see cref="TextWriter"/>. 439 /// </summary> 440 /// <param name="textWriter">The <see cref="System.IO.TextWriter"/> used to write text-based JSON.</param> Save(TextWriter textWriter)441 public void Save(TextWriter textWriter) 442 { 443 if (JsonType == JsonType.Default) 444 { 445 throw new InvalidOperationException(Properties.Resources.UseOfDefaultNotAllowed); 446 } 447 448 if (textWriter == null) 449 { 450 throw new ArgumentNullException("textWriter"); 451 } 452 453 using (MemoryStream ms = new MemoryStream()) 454 { 455 Save(ms); 456 ms.Position = 0; 457 textWriter.Write(new StreamReader(ms).ReadToEnd()); 458 } 459 } 460 461 /// <summary> 462 /// Provides a textual representation of this <see cref="System.Json.JsonValue"/> instance. 463 /// </summary> 464 /// <returns>A <see cref="System.String"/> containing text-based JSON.</returns> ToString()465 public override string ToString() 466 { 467 if (JsonType == JsonType.Default) 468 { 469 return "Default"; 470 } 471 472 using (MemoryStream ms = new MemoryStream()) 473 { 474 Save(ms); 475 ms.Position = 0; 476 return new StreamReader(ms).ReadToEnd(); 477 } 478 } 479 480 /// <summary> 481 /// Checks whether a key/value pair with a specified key exists in the JSON CLR object type. 482 /// </summary> 483 /// <param name="key">The key to check for.</param> 484 /// <returns>false in this class; subclasses may override this method to return other values.</returns> 485 /// <remarks>This method is overloaded in the implementation of the <see cref="System.Json.JsonObject"/> 486 /// class, which inherits from this class.</remarks> ContainsKey(string key)487 public virtual bool ContainsKey(string key) 488 { 489 return false; 490 } 491 492 /// <summary> 493 /// Returns the value returned by the safe string indexer for this instance. 494 /// </summary> 495 /// <param name="key">The key of the element to get.</param> 496 /// <returns>If this is an instance of <see cref="System.Json.JsonObject"/>, it contains 497 /// the given key and the value corresponding to the key is not null, then it will return that value. 498 /// Otherwise it will return a <see cref="System.Json.JsonValue"/> instance with <see cref="System.Json.JsonValue.JsonType"/> 499 /// equals to <see cref="F:System.Json.JsonType.Default"/>.</returns> 500 [EditorBrowsable(EditorBrowsableState.Never)] GetValue(string key)501 public virtual JsonValue GetValue(string key) 502 { 503 return ValueOrDefault(key); 504 } 505 506 /// <summary> 507 /// Returns the value returned by the safe int indexer for this instance. 508 /// </summary> 509 /// <param name="index">The zero-based index of the element to get.</param> 510 /// <returns>If this is an instance of <see cref="System.Json.JsonArray"/>, the index is within the array 511 /// bounds, and the value corresponding to the index is not null, then it will return that value. 512 /// Otherwise it will return a <see cref="System.Json.JsonValue"/> instance with <see cref="System.Json.JsonValue.JsonType"/> 513 /// equals to <see cref="F:System.Json.JsonType.Default"/>.</returns> 514 [EditorBrowsable(EditorBrowsableState.Never)] GetValue(int index)515 public virtual JsonValue GetValue(int index) 516 { 517 return ValueOrDefault(index); 518 } 519 520 /// <summary> 521 /// Sets the value and returns it. 522 /// </summary> 523 /// <param name="key">The key of the element to set.</param> 524 /// <param name="value">The value to be set.</param> 525 /// <returns>The value, converted into a JsonValue, set in this collection.</returns> 526 /// <exception cref="System.ArgumentException">If the value cannot be converted into a JsonValue.</exception> 527 [EditorBrowsable(EditorBrowsableState.Never)] SetValue(string key, object value)528 public virtual JsonValue SetValue(string key, object value) 529 { 530 this[key] = ResolveObject(value); 531 return this[key]; 532 } 533 534 /// <summary> 535 /// Sets the value and returns it. 536 /// </summary> 537 /// <param name="index">The zero-based index of the element to set.</param> 538 /// <param name="value">The value to be set.</param> 539 /// <returns>The value, converted into a JsonValue, set in this collection.</returns> 540 /// <exception cref="System.ArgumentException">If the value cannot be converted into a JsonValue.</exception> 541 [EditorBrowsable(EditorBrowsableState.Never)] SetValue(int index, object value)542 public virtual JsonValue SetValue(int index, object value) 543 { 544 this[index] = ResolveObject(value); 545 return this[index]; 546 } 547 548 /// <summary> 549 /// Safe string indexer for the <see cref="System.Json.JsonValue"/> type. 550 /// </summary> 551 /// <param name="key">The key of the element to get.</param> 552 /// <returns>If this is an instance of <see cref="System.Json.JsonObject"/>, it contains 553 /// the given key and the value corresponding to the key is not null, then it will return that value. 554 /// Otherwise it will return a <see cref="System.Json.JsonValue"/> instance with <see cref="System.Json.JsonValue.JsonType"/> 555 /// equals to <see cref="F:System.Json.JsonType.Default"/>.</returns> ValueOrDefault(string key)556 public virtual JsonValue ValueOrDefault(string key) 557 { 558 return JsonValue.DefaultInstance; 559 } 560 561 /// <summary> 562 /// Safe indexer for the <see cref="System.Json.JsonValue"/> type. 563 /// </summary> 564 /// <param name="index">The zero-based index of the element to get.</param> 565 /// <returns>If this is an instance of <see cref="System.Json.JsonArray"/>, the index is within the array 566 /// bounds, and the value corresponding to the index is not null, then it will return that value. 567 /// Otherwise it will return a <see cref="System.Json.JsonValue"/> instance with <see cref="System.Json.JsonValue.JsonType"/> 568 /// equals to <see cref="F:System.Json.JsonType.Default"/>.</returns> ValueOrDefault(int index)569 public virtual JsonValue ValueOrDefault(int index) 570 { 571 return JsonValue.DefaultInstance; 572 } 573 574 /// <summary> 575 /// Safe deep indexer for the <see cref="JsonValue"/> type. 576 /// </summary> 577 /// <param name="indexes">The indices to index this type. The indices can be 578 /// of type <see cref="System.Int32"/> or <see cref="System.String"/>.</param> 579 /// <returns>A <see cref="JsonValue"/> which is equivalent to calling<see cref="ValueOrDefault(int)"/> or 580 /// <see cref="ValueOrDefault(string)"/> on the first index, then calling it again on the result 581 /// for the second index and so on.</returns> 582 /// <exception cref="System.ArgumentException">If any of the indices is not of type 583 /// <see cref="System.Int32"/> or <see cref="System.String"/>.</exception> ValueOrDefault(params object[] indexes)584 public JsonValue ValueOrDefault(params object[] indexes) 585 { 586 if (indexes == null) 587 { 588 return JsonValue.DefaultInstance; 589 } 590 591 if (indexes.Length == 0) 592 { 593 return this; 594 } 595 596 JsonValue result = this; 597 for (int i = 0; i < indexes.Length; i++) 598 { 599 object index = indexes[i]; 600 if (index == null) 601 { 602 result = JsonValue.DefaultInstance; 603 continue; 604 } 605 606 Type indexType = index.GetType(); 607 608 switch (Type.GetTypeCode(indexType)) 609 { 610 case TypeCode.Char: 611 case TypeCode.Int16: 612 case TypeCode.UInt16: 613 case TypeCode.Byte: 614 case TypeCode.SByte: 615 index = System.Convert.ChangeType(index, typeof(int), CultureInfo.InvariantCulture); 616 goto case TypeCode.Int32; 617 618 case TypeCode.Int32: 619 result = result.ValueOrDefault((int)index); 620 break; 621 622 case TypeCode.String: 623 result = result.ValueOrDefault((string)index); 624 break; 625 626 default: 627 throw new ArgumentException(RS.Format(Properties.Resources.InvalidIndexType, index.GetType()), "indexes"); 628 } 629 } 630 631 return result; 632 } 633 634 #if FEATURE_DYNAMIC 635 [SuppressMessage("Microsoft.Design", "CA1033:InterfaceMethodsShouldBeCallableByChildTypes", 636 Justification = "Cannot make this class sealed, it needs to have subclasses. But its subclasses are sealed themselves.")] IDynamicMetaObjectProvider.GetMetaObject(Expression parameter)637 DynamicMetaObject IDynamicMetaObjectProvider.GetMetaObject(Expression parameter) 638 { 639 if (parameter == null) 640 { 641 throw new ArgumentNullException("parameter"); 642 } 643 644 return new JsonValueDynamicMetaObject(parameter, this); 645 } 646 #endif 647 648 /// <summary> 649 /// Resolves the specified object to an appropriate JsonValue instance. 650 /// </summary> 651 /// <param name="value">The object to resolve.</param> 652 /// <returns>A <see cref="JsonValue"/> instance resolved from the specified object.</returns> ResolveObject(object value)653 internal static JsonValue ResolveObject(object value) 654 { 655 JsonPrimitive primitive; 656 657 if (value == null) 658 { 659 return null; 660 } 661 662 JsonValue jsonValue = value as JsonValue; 663 664 if (jsonValue != null) 665 { 666 return jsonValue; 667 } 668 669 if (JsonPrimitive.TryCreate(value, out primitive)) 670 { 671 return primitive; 672 } 673 674 throw new ArgumentException(Properties.Resources.TypeNotSupported, "value"); 675 } 676 677 /// <summary> 678 /// Determines whether an explicit cast to JsonValue is provided from the specified type. 679 /// </summary> 680 /// <param name="type">The type to check.</param> 681 /// <returns>true if an explicit cast exists for the specified type, false otherwise.</returns> IsSupportedExplicitCastType(Type type)682 internal static bool IsSupportedExplicitCastType(Type type) 683 { 684 TypeCode typeCode = Type.GetTypeCode(type); 685 686 switch (typeCode) 687 { 688 case TypeCode.Boolean: 689 case TypeCode.Byte: 690 case TypeCode.Char: 691 case TypeCode.DateTime: 692 case TypeCode.Decimal: 693 case TypeCode.Double: 694 case TypeCode.Int16: 695 case TypeCode.Int32: 696 case TypeCode.Int64: 697 case TypeCode.SByte: 698 case TypeCode.Single: 699 case TypeCode.String: 700 case TypeCode.UInt16: 701 case TypeCode.UInt32: 702 case TypeCode.UInt64: 703 return true; 704 705 default: 706 return type == typeof(DateTimeOffset) || type == typeof(Guid) || type == typeof(Uri) || 707 type == typeof(List<object>) || type == typeof(Array) || type == typeof(object[]) || 708 type == typeof(Dictionary<string, object>); 709 } 710 } 711 712 /// <summary> 713 /// Returns the value this object wraps (if any). 714 /// </summary> 715 /// <returns>The value wrapped by this instance or null if none.</returns> Read()716 internal virtual object Read() 717 { 718 return null; 719 } 720 721 /// <summary> 722 /// Serializes this object into the specified <see cref="XmlDictionaryWriter"/> instance. 723 /// </summary> 724 /// <param name="jsonWriter">An <see cref="XmlDictionaryWriter"/> instance to serialize this instance into.</param> Save(XmlDictionaryWriter jsonWriter)725 internal virtual void Save(XmlDictionaryWriter jsonWriter) 726 { 727 if (jsonWriter == null) 728 { 729 throw new ArgumentNullException("jsonWriter"); 730 } 731 732 Stack<JsonValue> objectStack = new Stack<JsonValue>(); 733 Stack<int> indexStack = new Stack<int>(); 734 int currentIndex = 0; 735 JsonValue currentValue = this; 736 737 OnSaveStarted(); 738 739 WriteAttributeString(jsonWriter); 740 741 while (currentIndex < currentValue.Count || objectStack.Count > 0) 742 { 743 if (currentValue.Count > currentIndex) 744 { 745 JsonValue nextValue = currentValue.WriteStartElementAndGetNext(jsonWriter, currentIndex); 746 747 if (JsonValue.IsJsonCollection(nextValue)) 748 { 749 nextValue.OnSaveStarted(); 750 nextValue.WriteAttributeString(jsonWriter); 751 752 objectStack.Push(currentValue); 753 indexStack.Push(currentIndex); 754 currentValue = nextValue; 755 currentIndex = 0; 756 } 757 else 758 { 759 if (nextValue == null) 760 { 761 jsonWriter.WriteAttributeString(JXmlToJsonValueConverter.TypeAttributeName, JXmlToJsonValueConverter.NullAttributeValue); 762 } 763 else 764 { 765 nextValue.Save(jsonWriter); 766 } 767 768 currentIndex++; 769 jsonWriter.WriteEndElement(); 770 } 771 } 772 else 773 { 774 if (objectStack.Count > 0) 775 { 776 currentValue.OnSaveEnded(); 777 jsonWriter.WriteEndElement(); 778 779 currentValue = objectStack.Pop(); 780 currentIndex = indexStack.Pop() + 1; 781 } 782 } 783 } 784 785 OnSaveEnded(); 786 } 787 788 /// <summary> 789 /// Returns an enumerator which iterates through the values in this object. 790 /// </summary> 791 /// <returns>An <see cref="System.Collections.IEnumerator"/> which iterates through the values in this object.</returns> 792 /// <remarks>This method is the virtual version of the IEnumerator.GetEnumerator method and is provided to allow derived classes to implement the 793 /// appropriate version of the generic interface (enumerator of values or key/value pairs).</remarks> 794 [SuppressMessage("Microsoft.Design", "CA1024:UsePropertiesWhereAppropriate", 795 Justification = "This method is a virtual version of the IEnumerable.GetEnumerator method.")] 796 [SuppressMessage("Microsoft.Design", "CA1006:DoNotNestGenericTypesInMemberSignatures", 797 Justification = "This class is a collection that is properly represented by the nested generic type.")] GetKeyValuePairEnumerator()798 protected virtual IEnumerator<KeyValuePair<string, JsonValue>> GetKeyValuePairEnumerator() 799 { 800 yield break; 801 } 802 803 /// <summary> 804 /// Callback method called during Save operations to let the instance write the start element 805 /// and return the next element in the collection. 806 /// </summary> 807 /// <param name="jsonWriter">The JXML writer used to write JSON.</param> 808 /// <param name="index">The index within this collection.</param> 809 /// <returns>The next item in the collection, or null of there are no more items.</returns> WriteStartElementAndGetNext(XmlDictionaryWriter jsonWriter, int index)810 internal virtual JsonValue WriteStartElementAndGetNext(XmlDictionaryWriter jsonWriter, int index) 811 { 812 return null; 813 } 814 815 /// <summary> 816 /// Callback method called to let an instance write the proper JXML attribute when saving this 817 /// instance. 818 /// </summary> 819 /// <param name="jsonWriter">The JXML writer used to write JSON.</param> WriteAttributeString(XmlDictionaryWriter jsonWriter)820 internal virtual void WriteAttributeString(XmlDictionaryWriter jsonWriter) 821 { 822 } 823 824 /// <summary> 825 /// Callback method called when a Save operation is starting for this instance. 826 /// </summary> OnSaveStarted()827 protected virtual void OnSaveStarted() 828 { 829 } 830 831 /// <summary> 832 /// Callback method called when a Save operation is finished for this instance. 833 /// </summary> OnSaveEnded()834 protected virtual void OnSaveEnded() 835 { 836 } 837 838 /// <summary> 839 /// Called internally to raise the <see cref="Changing"/> event. 840 /// </summary> 841 /// <param name="sender">The object which caused the event to be raised.</param> 842 /// <param name="eventArgs">The arguments to the event.</param> 843 [SuppressMessage("Microsoft.Design", "CA1030:UseEventsWhereAppropriate", 844 Justification = "This is a helper function used to raise the event.")] 845 [SuppressMessage("Microsoft.Security", "CA2109:ReviewVisibleEventHandlers", 846 Justification = "This is not externally visible, since the constructor for this class is internal (cannot be directly derived) and all its subclasses are sealed.")] RaiseChangingEvent(object sender, JsonValueChangeEventArgs eventArgs)847 protected void RaiseChangingEvent(object sender, JsonValueChangeEventArgs eventArgs) 848 { 849 EventHandler<JsonValueChangeEventArgs> changing = OnChanging; 850 if (changing != null) 851 { 852 changing(sender, eventArgs); 853 } 854 } 855 856 /// <summary> 857 /// Called internally to raise the <see cref="Changed"/> event. 858 /// </summary> 859 /// <param name="sender">The object which caused the event to be raised.</param> 860 /// <param name="eventArgs">The arguments to the event.</param> 861 [SuppressMessage("Microsoft.Design", "CA1030:UseEventsWhereAppropriate", 862 Justification = "This is a helper function used to raise the event.")] 863 [SuppressMessage("Microsoft.Security", "CA2109:ReviewVisibleEventHandlers", 864 Justification = "This is not externally visible, since the constructor for this class is internal (cannot be directly derived) and all its subclasses are sealed.")] RaiseChangedEvent(object sender, JsonValueChangeEventArgs eventArgs)865 protected void RaiseChangedEvent(object sender, JsonValueChangeEventArgs eventArgs) 866 { 867 EventHandler<JsonValueChangeEventArgs> changed = OnChanged; 868 if (changed != null) 869 { 870 changed(sender, eventArgs); 871 } 872 } 873 IsJsonCollection(JsonValue value)874 private static bool IsJsonCollection(JsonValue value) 875 { 876 return value != null && (value.JsonType == JsonType.Array || value.JsonType == JsonType.Object); 877 } 878 879 /// <summary> 880 /// Enables explicit casts from an instance of type <see cref="System.Json.JsonValue"/> to a <see cref="System.String"/> object. 881 /// </summary> 882 /// <param name="value">The instance of <see cref="System.Json.JsonValue"/> used to initialize the <see cref="System.String"/> object.</param> 883 /// <returns>The <see cref="System.String"/> initialized with the <see cref="System.Json.JsonValue"/> value specified or null if value is null.</returns> operator string(JsonValue value)884 public static explicit operator string(JsonValue value) 885 { 886 return CastValue<string>(value); 887 } 888 889 /// <summary> 890 /// Enables explicit casts from an instance of type <see cref="System.Json.JsonValue"/> to a <see cref="System.Double"/> object. 891 /// </summary> 892 /// <param name="value">The instance of <see cref="System.Json.JsonValue"/> used to initialize the <see cref="System.Double"/> object.</param> 893 /// <returns>The <see cref="System.Double"/> initialized with the <see cref="System.Json.JsonValue"/> value specified.</returns> operator double(JsonValue value)894 public static explicit operator double(JsonValue value) 895 { 896 return CastValue<double>(value); 897 } 898 899 /// <summary> 900 /// Enables explicit casts from an instance of type <see cref="System.Json.JsonValue"/> to a <see cref="System.Single"/> object. 901 /// </summary> 902 /// <param name="value">The instance of <see cref="System.Json.JsonValue"/> used to initialize the <see cref="System.Single"/> object.</param> 903 /// <returns>The <see cref="System.Single"/> initialized with the <see cref="System.Json.JsonValue"/> value specified.</returns> operator float(JsonValue value)904 public static explicit operator float(JsonValue value) 905 { 906 return CastValue<float>(value); 907 } 908 909 /// <summary> 910 /// Enables explicit casts from an instance of type <see cref="System.Json.JsonValue"/> to a <see cref="System.Decimal"/> object. 911 /// </summary> 912 /// <param name="value">The instance of <see cref="System.Json.JsonValue"/> used to initialize the <see cref="System.Decimal"/> object.</param> 913 /// <returns>The <see cref="System.Decimal"/> initialized with the <see cref="System.Json.JsonValue"/> value specified.</returns> operator decimal(JsonValue value)914 public static explicit operator decimal(JsonValue value) 915 { 916 return CastValue<decimal>(value); 917 } 918 919 /// <summary> 920 /// Enables explicit casts from an instance of type <see cref="System.Json.JsonValue"/> to a <see cref="System.Int64"/> object. 921 /// </summary> 922 /// <param name="value">The instance of <see cref="System.Json.JsonValue"/> used to initialize the <see cref="System.Int64"/> object.</param> 923 /// <returns>The <see cref="System.Int64"/> initialized with the <see cref="System.Json.JsonValue"/> value specified.</returns> operator long(JsonValue value)924 public static explicit operator long(JsonValue value) 925 { 926 return CastValue<long>(value); 927 } 928 929 /// <summary> 930 /// Enables explicit casts from an instance of type <see cref="System.Json.JsonValue"/> to a <see cref="System.UInt64"/> object. 931 /// </summary> 932 /// <param name="value">The instance of <see cref="System.Json.JsonValue"/> used to initialize the <see cref="System.UInt64"/> object.</param> 933 /// <returns>The <see cref="System.UInt64"/> initialized with the <see cref="System.Json.JsonValue"/> value specified.</returns> 934 [CLSCompliant(false)] operator ulong(JsonValue value)935 public static explicit operator ulong(JsonValue value) 936 { 937 return CastValue<ulong>(value); 938 } 939 940 /// <summary> 941 /// Enables explicit casts from an instance of type <see cref="System.Json.JsonValue"/> to a <see cref="System.Int32"/> object. 942 /// </summary> 943 /// <param name="value">The instance of <see cref="System.Json.JsonValue"/> used to initialize the <see cref="System.Int32"/> object.</param> 944 /// <returns>The <see cref="System.Int32"/> initialized with the <see cref="System.Json.JsonValue"/> value specified.</returns> operator int(JsonValue value)945 public static explicit operator int(JsonValue value) 946 { 947 return CastValue<int>(value); 948 } 949 950 /// <summary> 951 /// Enables explicit casts from an instance of type <see cref="System.Json.JsonValue"/> to a <see cref="System.UInt32"/> object. 952 /// </summary> 953 /// <param name="value">The instance of <see cref="System.Json.JsonValue"/> used to initialize the <see cref="System.UInt32"/> object.</param> 954 /// <returns>The <see cref="System.UInt32"/> initialized with the <see cref="System.Json.JsonValue"/> value specified.</returns> 955 [CLSCompliant(false)] operator uint(JsonValue value)956 public static explicit operator uint(JsonValue value) 957 { 958 return CastValue<uint>(value); 959 } 960 961 /// <summary> 962 /// Enables explicit casts from an instance of type <see cref="System.Json.JsonValue"/> to a <see cref="System.Int16"/> object. 963 /// </summary> 964 /// <param name="value">The instance of <see cref="System.Json.JsonValue"/> used to initialize the <see cref="System.Int16"/> object.</param> 965 /// <returns>The <see cref="System.Int16"/> initialized with the <see cref="System.Json.JsonValue"/> value specified.</returns> operator short(JsonValue value)966 public static explicit operator short(JsonValue value) 967 { 968 return CastValue<short>(value); 969 } 970 971 /// <summary> 972 /// Enables explicit casts from an instance of type <see cref="System.Json.JsonValue"/> to a <see cref="System.UInt16"/> object. 973 /// </summary> 974 /// <param name="value">The instance of <see cref="System.Json.JsonValue"/> used to initialize the <see cref="System.UInt16"/> object.</param> 975 /// <returns>The <see cref="System.UInt16"/> initialized with the <see cref="System.Json.JsonValue"/> value specified.</returns> 976 [CLSCompliant(false)] operator ushort(JsonValue value)977 public static explicit operator ushort(JsonValue value) 978 { 979 return CastValue<ushort>(value); 980 } 981 982 /// <summary> 983 /// Enables explicit casts from an instance of type <see cref="System.Json.JsonValue"/> to a <see cref="System.SByte"/> object. 984 /// </summary> 985 /// <param name="value">The instance of <see cref="System.Json.JsonValue"/> used to initialize the <see cref="System.SByte"/> object.</param> 986 /// <returns>The <see cref="System.SByte"/> initialized with the <see cref="System.Json.JsonValue"/> value specified.</returns> 987 [CLSCompliant(false)] operator sbyte(JsonValue value)988 public static explicit operator sbyte(JsonValue value) 989 { 990 return CastValue<sbyte>(value); 991 } 992 993 /// <summary> 994 /// Enables explicit casts from an instance of type <see cref="System.Json.JsonValue"/> to a <see cref="System.Byte"/> object. 995 /// </summary> 996 /// <param name="value">The instance of <see cref="System.Json.JsonValue"/> used to initialize the <see cref="System.Byte"/> object.</param> 997 /// <returns>The <see cref="System.Byte"/> initialized with the <see cref="System.Json.JsonValue"/> value specified.</returns> operator byte(JsonValue value)998 public static explicit operator byte(JsonValue value) 999 { 1000 return CastValue<byte>(value); 1001 } 1002 1003 /// <summary> 1004 /// Enables explicit casts from an instance of type <see cref="System.Json.JsonValue"/> to a <see cref="System.Uri"/> object. 1005 /// </summary> 1006 /// <param name="value">The instance of <see cref="System.Json.JsonValue"/> used to initialize the <see cref="System.Uri"/> object.</param> 1007 /// <returns>The <see cref="System.Uri"/> initialized with the <see cref="System.Json.JsonValue"/> value specified or null if value is null.</returns> operator Uri(JsonValue value)1008 public static explicit operator Uri(JsonValue value) 1009 { 1010 return CastValue<Uri>(value); 1011 } 1012 1013 /// <summary> 1014 /// Enables explicit casts from an instance of type <see cref="System.Json.JsonValue"/> to a <see cref="System.Guid"/> object. 1015 /// </summary> 1016 /// <param name="value">The instance of <see cref="System.Json.JsonValue"/> used to initialize the <see cref="System.Guid"/> object.</param> 1017 /// <returns>The <see cref="System.Guid"/> initialized with the <see cref="System.Json.JsonValue"/> value specified.</returns> operator Guid(JsonValue value)1018 public static explicit operator Guid(JsonValue value) 1019 { 1020 return CastValue<Guid>(value); 1021 } 1022 1023 /// <summary> 1024 /// Enables explicit casts from an instance of type <see cref="System.Json.JsonValue"/> to a <see cref="System.DateTime"/> object. 1025 /// </summary> 1026 /// <param name="value">The instance of <see cref="System.Json.JsonValue"/> used to initialize the <see cref="System.DateTime"/> object.</param> 1027 /// <returns>The <see cref="System.DateTime"/> initialized with the <see cref="System.Json.JsonValue"/> value specified.</returns> operator DateTime(JsonValue value)1028 public static explicit operator DateTime(JsonValue value) 1029 { 1030 return CastValue<DateTime>(value); 1031 } 1032 1033 /// <summary> 1034 /// Enables explicit casts from an instance of type <see cref="System.Json.JsonValue"/> to a <see cref="System.Char"/> object. 1035 /// </summary> 1036 /// <param name="value">The instance of <see cref="System.Json.JsonValue"/> used to initialize the <see cref="System.Char"/> object.</param> 1037 /// <returns>The <see cref="System.Char"/> initialized with the <see cref="System.Json.JsonValue"/> value specified.</returns> operator char(JsonValue value)1038 public static explicit operator char(JsonValue value) 1039 { 1040 return CastValue<char>(value); 1041 } 1042 1043 /// <summary> 1044 /// Enables explicit casts from an instance of type <see cref="System.Json.JsonValue"/> to a <see cref="System.Boolean"/> object. 1045 /// </summary> 1046 /// <param name="value">The instance of <see cref="System.Json.JsonValue"/> used to initialize the <see cref="System.Boolean"/> object.</param> 1047 /// <returns>The <see cref="System.Boolean"/> initialized with the <see cref="System.Json.JsonValue"/> value specified.</returns> operator bool(JsonValue value)1048 public static explicit operator bool(JsonValue value) 1049 { 1050 return CastValue<bool>(value); 1051 } 1052 1053 /// <summary> 1054 /// Enables explicit casts from an instance of type <see cref="System.Json.JsonValue"/> to a <see cref="System.DateTimeOffset"/> object. 1055 /// </summary> 1056 /// <param name="value">The instance of <see cref="System.Json.JsonValue"/> used to initialize the <see cref="System.DateTimeOffset"/> object.</param> 1057 /// <returns>The <see cref="System.DateTimeOffset"/> initialized with the <see cref="System.Json.JsonValue"/> value specified.</returns> operator DateTimeOffset(JsonValue value)1058 public static explicit operator DateTimeOffset(JsonValue value) 1059 { 1060 return CastValue<DateTimeOffset>(value); 1061 } 1062 1063 /// <summary> 1064 /// Enables implicit casts from type <see cref="System.Boolean"/> to a <see cref="System.Json.JsonPrimitive"/>. 1065 /// </summary> 1066 /// <param name="value">The <see cref="System.Boolean"/> instance used to initialize the <see cref="System.Json.JsonPrimitive"/>.</param> 1067 /// <returns>The <see cref="System.Json.JsonValue"/> initialized with the <see cref="System.Boolean"/> specified.</returns> operator JsonValue(bool value)1068 public static implicit operator JsonValue(bool value) 1069 { 1070 return new JsonPrimitive(value); 1071 } 1072 1073 /// <summary> 1074 /// Enables implicit casts from type <see cref="System.Byte"/> to a <see cref="System.Json.JsonPrimitive"/>. 1075 /// </summary> 1076 /// <param name="value">The <see cref="System.Byte"/> instance used to initialize the <see cref="System.Json.JsonPrimitive"/>.</param> 1077 /// <returns>The <see cref="System.Json.JsonValue"/> initialized with the <see cref="System.Byte"/> specified.</returns> operator JsonValue(byte value)1078 public static implicit operator JsonValue(byte value) 1079 { 1080 return new JsonPrimitive(value); 1081 } 1082 1083 /// <summary> 1084 /// Enables implicit casts from type <see cref="System.Decimal"/> to a <see cref="System.Json.JsonPrimitive"/>. 1085 /// </summary> 1086 /// <param name="value">The <see cref="System.Decimal"/> instance used to initialize the <see cref="System.Json.JsonPrimitive"/>.</param> 1087 /// <returns>The <see cref="System.Json.JsonValue"/> initialized with the <see cref="System.Decimal"/> specified.</returns> operator JsonValue(decimal value)1088 public static implicit operator JsonValue(decimal value) 1089 { 1090 return new JsonPrimitive(value); 1091 } 1092 1093 /// <summary> 1094 /// Enables implicit casts from type <see cref="System.Double"/> to a <see cref="System.Json.JsonPrimitive"/>. 1095 /// </summary> 1096 /// <param name="value">The <see cref="System.Double"/> instance used to initialize the <see cref="System.Json.JsonPrimitive"/>.</param> 1097 /// <returns>The <see cref="System.Json.JsonValue"/> initialized with the <see cref="System.Double"/> specified.</returns> operator JsonValue(double value)1098 public static implicit operator JsonValue(double value) 1099 { 1100 return new JsonPrimitive(value); 1101 } 1102 1103 /// <summary> 1104 /// Enables implicit casts from type <see cref="System.Int16"/> to a <see cref="System.Json.JsonPrimitive"/>. 1105 /// </summary> 1106 /// <param name="value">The <see cref="System.Int16"/> instance used to initialize the <see cref="System.Json.JsonPrimitive"/>.</param> 1107 /// <returns>The <see cref="System.Json.JsonValue"/> initialized with the <see cref="System.Int16"/> specified.</returns> operator JsonValue(short value)1108 public static implicit operator JsonValue(short value) 1109 { 1110 return new JsonPrimitive(value); 1111 } 1112 1113 /// <summary> 1114 /// Enables implicit casts from type <see cref="System.Int32"/> to a <see cref="System.Json.JsonPrimitive"/>. 1115 /// </summary> 1116 /// <param name="value">The <see cref="System.Int32"/> instance used to initialize the <see cref="System.Json.JsonPrimitive"/>.</param> 1117 /// <returns>The <see cref="System.Json.JsonValue"/> initialized with the <see cref="System.Int32"/> specified.</returns> operator JsonValue(int value)1118 public static implicit operator JsonValue(int value) 1119 { 1120 return new JsonPrimitive(value); 1121 } 1122 1123 /// <summary> 1124 /// Enables implicit casts from type <see cref="System.Int64"/> to a <see cref="System.Json.JsonPrimitive"/>. 1125 /// </summary> 1126 /// <param name="value">The <see cref="System.Int64"/> instance used to initialize the <see cref="System.Json.JsonPrimitive"/>.</param> 1127 /// <returns>The <see cref="System.Json.JsonValue"/> initialized with the <see cref="System.Int64"/> specified.</returns> operator JsonValue(long value)1128 public static implicit operator JsonValue(long value) 1129 { 1130 return new JsonPrimitive(value); 1131 } 1132 1133 /// <summary> 1134 /// Enables implicit casts from type <see cref="System.Single"/> to a <see cref="System.Json.JsonPrimitive"/>. 1135 /// </summary> 1136 /// <param name="value">The <see cref="System.Single"/> instance used to initialize the <see cref="System.Json.JsonPrimitive"/>.</param> 1137 /// <returns>The <see cref="System.Json.JsonValue"/> initialized with the <see cref="System.Single"/> specified.</returns> operator JsonValue(float value)1138 public static implicit operator JsonValue(float value) 1139 { 1140 return new JsonPrimitive(value); 1141 } 1142 1143 /// <summary> 1144 /// Enables implicit casts from type <see cref="System.String"/> to a <see cref="System.Json.JsonPrimitive"/>. 1145 /// </summary> 1146 /// <param name="value">The <see cref="System.String"/> instance used to initialize the <see cref="System.Json.JsonPrimitive"/>.</param> 1147 /// <returns>The <see cref="System.Json.JsonValue"/> initialized with the <see cref="System.String"/> specified, or null if the value is null.</returns> 1148 [SuppressMessage("Microsoft.Design", "CA1057:StringUriOverloadsCallSystemUriOverloads", 1149 Justification = "This operator does not intend to represent a Uri overload.")] operator JsonValue(string value)1150 public static implicit operator JsonValue(string value) 1151 { 1152 return value == null ? null : new JsonPrimitive(value); 1153 } 1154 1155 /// <summary> 1156 /// Enables implicit casts from type <see cref="System.Char"/> to a <see cref="System.Json.JsonPrimitive"/>. 1157 /// </summary> 1158 /// <param name="value">The <see cref="System.Char"/> instance used to initialize the <see cref="System.Json.JsonPrimitive"/>.</param> 1159 /// <returns>The <see cref="System.Json.JsonValue"/> initialized with the <see cref="System.Char"/> specified.</returns> operator JsonValue(char value)1160 public static implicit operator JsonValue(char value) 1161 { 1162 return new JsonPrimitive(value); 1163 } 1164 1165 /// <summary> 1166 /// Enables implicit casts from type <see cref="System.DateTime"/> to a <see cref="System.Json.JsonPrimitive"/>. 1167 /// </summary> 1168 /// <param name="value">The <see cref="System.DateTime"/> instance used to initialize the <see cref="System.Json.JsonPrimitive"/>.</param> 1169 /// <returns>The <see cref="System.Json.JsonValue"/> initialized with the <see cref="System.DateTime"/> specified.</returns> operator JsonValue(DateTime value)1170 public static implicit operator JsonValue(DateTime value) 1171 { 1172 return new JsonPrimitive(value); 1173 } 1174 1175 /// <summary> 1176 /// Enables implicit casts from type <see cref="System.Guid"/> to a <see cref="System.Json.JsonPrimitive"/>. 1177 /// </summary> 1178 /// <param name="value">The <see cref="System.Guid"/> instance used to initialize the <see cref="System.Json.JsonPrimitive"/>.</param> 1179 /// <returns>The <see cref="System.Json.JsonValue"/> initialized with the <see cref="System.Guid"/> specified.</returns> operator JsonValue(Guid value)1180 public static implicit operator JsonValue(Guid value) 1181 { 1182 return new JsonPrimitive(value); 1183 } 1184 1185 /// <summary> 1186 /// Enables implicit casts from type <see cref="System.Uri"/> to a <see cref="System.Json.JsonPrimitive"/>. 1187 /// </summary> 1188 /// <param name="value">The <see cref="System.Uri"/> instance used to initialize the <see cref="System.Json.JsonPrimitive"/>.</param> 1189 /// <returns>The <see cref="System.Json.JsonValue"/> initialized with the <see cref="System.Uri"/> specified, or null if the value is null.</returns> operator JsonValue(Uri value)1190 public static implicit operator JsonValue(Uri value) 1191 { 1192 return value == null ? null : new JsonPrimitive(value); 1193 } 1194 1195 /// <summary> 1196 /// Enables implicit casts from type <see cref="System.SByte"/> to a <see cref="System.Json.JsonPrimitive"/>. 1197 /// </summary> 1198 /// <param name="value">The <see cref="System.SByte"/> instance used to initialize the <see cref="System.Json.JsonPrimitive"/>.</param> 1199 /// <returns>The <see cref="System.Json.JsonValue"/> initialized with the <see cref="System.SByte"/> specified.</returns> 1200 [CLSCompliant(false)] operator JsonValue(sbyte value)1201 public static implicit operator JsonValue(sbyte value) 1202 { 1203 return new JsonPrimitive(value); 1204 } 1205 1206 /// <summary> 1207 /// Enables implicit casts from type <see cref="System.UInt16"/> to a <see cref="System.Json.JsonPrimitive"/>. 1208 /// </summary> 1209 /// <param name="value">The <see cref="System.UInt16"/> instance used to initialize the <see cref="System.Json.JsonPrimitive"/>.</param> 1210 /// <returns>The <see cref="System.Json.JsonValue"/> initialized with the <see cref="System.UInt16"/> specified.</returns> 1211 [CLSCompliant(false)] operator JsonValue(ushort value)1212 public static implicit operator JsonValue(ushort value) 1213 { 1214 return new JsonPrimitive(value); 1215 } 1216 1217 /// <summary> 1218 /// Enables implicit casts from type <see cref="System.UInt32"/> to a <see cref="System.Json.JsonPrimitive"/>. 1219 /// </summary> 1220 /// <param name="value">The <see cref="System.UInt32"/> instance used to initialize the <see cref="System.Json.JsonPrimitive"/>.</param> 1221 /// <returns>The <see cref="System.Json.JsonValue"/> initialized with the <see cref="System.UInt32"/> specified.</returns> 1222 [CLSCompliant(false)] operator JsonValue(uint value)1223 public static implicit operator JsonValue(uint value) 1224 { 1225 return new JsonPrimitive(value); 1226 } 1227 1228 /// <summary> 1229 /// Enables implicit casts from type <see cref="System.UInt64"/> to a <see cref="System.Json.JsonPrimitive"/>. 1230 /// </summary> 1231 /// <param name="value">The <see cref="System.UInt64"/> instance used to initialize the <see cref="System.Json.JsonPrimitive"/>.</param> 1232 /// <returns>The <see cref="System.Json.JsonValue"/> initialized with the <see cref="System.UInt64"/> specified.</returns> 1233 [CLSCompliant(false)] operator JsonValue(ulong value)1234 public static implicit operator JsonValue(ulong value) 1235 { 1236 return new JsonPrimitive(value); 1237 } 1238 1239 /// <summary> 1240 /// Enables implicit casts from type <see cref="System.DateTimeOffset"/> to a <see cref="System.Json.JsonPrimitive"/>. 1241 /// </summary> 1242 /// <param name="value">The <see cref="System.DateTimeOffset"/> instance used to initialize the <see cref="System.Json.JsonPrimitive"/>.</param> 1243 /// <returns>The <see cref="System.Json.JsonValue"/> initialized with the <see cref="System.DateTimeOffset"/> specified.</returns> operator JsonValue(DateTimeOffset value)1244 public static implicit operator JsonValue(DateTimeOffset value) 1245 { 1246 return new JsonPrimitive(value); 1247 } 1248 } 1249 } 1250