2
// Copyright (c) 2007 James Newton-King
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
13
// The above copyright notice and this permission notice shall be
14
// included in all copies or substantial portions of the Software.
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.
27
using System.Collections.Generic;
28
#if !(NET35 || NET20 || WINDOWS_PHONE || PORTABLE)
30
using System.Linq.Expressions;
33
using Newtonsoft.Json.Utilities;
34
using System.Diagnostics;
35
using System.Globalization;
36
using System.Collections;
38
using Newtonsoft.Json.Utilities.LinqBridge;
43
namespace Newtonsoft.Json.Linq
46
/// Represents an abstract JSON token.
48
public abstract class JToken : IJEnumerable<JToken>, IJsonLineInfo
49
#if !(SILVERLIGHT || NETFX_CORE || PORTABLE)
52
#if !(NET35 || NET20 || WINDOWS_PHONE || PORTABLE)
53
, IDynamicMetaObjectProvider
56
private JContainer _parent;
57
private JToken _previous;
59
private static JTokenEqualityComparer _equalityComparer;
61
private int? _lineNumber;
62
private int? _linePosition;
64
private static readonly JTokenType[] BooleanTypes = new[] { JTokenType.Integer, JTokenType.Float, JTokenType.String, JTokenType.Comment, JTokenType.Raw, JTokenType.Boolean };
65
private static readonly JTokenType[] NumberTypes = new[] { JTokenType.Integer, JTokenType.Float, JTokenType.String, JTokenType.Comment, JTokenType.Raw, JTokenType.Boolean };
66
private static readonly JTokenType[] StringTypes = new[] { JTokenType.Date, JTokenType.Integer, JTokenType.Float, JTokenType.String, JTokenType.Comment, JTokenType.Raw, JTokenType.Boolean, JTokenType.Bytes, JTokenType.Guid, JTokenType.TimeSpan, JTokenType.Uri };
67
private static readonly JTokenType[] GuidTypes = new[] { JTokenType.String, JTokenType.Comment, JTokenType.Raw, JTokenType.Guid };
68
private static readonly JTokenType[] TimeSpanTypes = new[] { JTokenType.String, JTokenType.Comment, JTokenType.Raw, JTokenType.TimeSpan };
69
private static readonly JTokenType[] UriTypes = new[] { JTokenType.String, JTokenType.Comment, JTokenType.Raw, JTokenType.Uri };
70
private static readonly JTokenType[] CharTypes = new[] { JTokenType.Integer, JTokenType.Float, JTokenType.String, JTokenType.Comment, JTokenType.Raw };
71
private static readonly JTokenType[] DateTimeTypes = new[] { JTokenType.Date, JTokenType.String, JTokenType.Comment, JTokenType.Raw };
72
private static readonly JTokenType[] BytesTypes = new[] { JTokenType.Bytes, JTokenType.String, JTokenType.Comment, JTokenType.Raw };
75
/// Gets a comparer that can compare two tokens for value equality.
77
/// <value>A <see cref="JTokenEqualityComparer"/> that can compare two nodes for value equality.</value>
78
public static JTokenEqualityComparer EqualityComparer
82
if (_equalityComparer == null)
83
_equalityComparer = new JTokenEqualityComparer();
85
return _equalityComparer;
90
/// Gets or sets the parent.
92
/// <value>The parent.</value>
93
public JContainer Parent
96
get { return _parent; }
97
internal set { _parent = value; }
101
/// Gets the root <see cref="JToken"/> of this <see cref="JToken"/>.
103
/// <value>The root <see cref="JToken"/> of this <see cref="JToken"/>.</value>
108
JContainer parent = Parent;
112
while (parent.Parent != null)
114
parent = parent.Parent;
121
internal abstract JToken CloneToken();
122
internal abstract bool DeepEquals(JToken node);
125
/// Gets the node type for this <see cref="JToken"/>.
127
/// <value>The type.</value>
128
public abstract JTokenType Type { get; }
131
/// Gets a value indicating whether this token has childen tokens.
134
/// <c>true</c> if this token has child values; otherwise, <c>false</c>.
136
public abstract bool HasValues { get; }
139
/// Compares the values of two tokens, including the values of all descendant tokens.
141
/// <param name="t1">The first <see cref="JToken"/> to compare.</param>
142
/// <param name="t2">The second <see cref="JToken"/> to compare.</param>
143
/// <returns>true if the tokens are equal; otherwise false.</returns>
144
public static bool DeepEquals(JToken t1, JToken t2)
146
return (t1 == t2 || (t1 != null && t2 != null && t1.DeepEquals(t2)));
150
/// Gets the next sibling token of this node.
152
/// <value>The <see cref="JToken"/> that contains the next sibling token.</value>
155
get { return _next; }
156
internal set { _next = value; }
160
/// Gets the previous sibling token of this node.
162
/// <value>The <see cref="JToken"/> that contains the previous sibling token.</value>
163
public JToken Previous
165
get { return _previous; }
166
internal set { _previous = value; }
174
/// Adds the specified content immediately after this token.
176
/// <param name="content">A content object that contains simple content or a collection of content objects to be added after this token.</param>
177
public void AddAfterSelf(object content)
180
throw new InvalidOperationException("The parent is missing.");
182
int index = _parent.IndexOfItem(this);
183
_parent.AddInternal(index + 1, content, false);
187
/// Adds the specified content immediately before this token.
189
/// <param name="content">A content object that contains simple content or a collection of content objects to be added before this token.</param>
190
public void AddBeforeSelf(object content)
193
throw new InvalidOperationException("The parent is missing.");
195
int index = _parent.IndexOfItem(this);
196
_parent.AddInternal(index, content, false);
200
/// Returns a collection of the ancestor tokens of this token.
202
/// <returns>A collection of the ancestor tokens of this token.</returns>
203
public IEnumerable<JToken> Ancestors()
205
for (JToken parent = Parent; parent != null; parent = parent.Parent)
212
/// Returns a collection of the sibling tokens after this token, in document order.
214
/// <returns>A collection of the sibling tokens after this tokens, in document order.</returns>
215
public IEnumerable<JToken> AfterSelf()
220
for (JToken o = Next; o != null; o = o.Next)
227
/// Returns a collection of the sibling tokens before this token, in document order.
229
/// <returns>A collection of the sibling tokens before this token, in document order.</returns>
230
public IEnumerable<JToken> BeforeSelf()
232
for (JToken o = Parent.First; o != this; o = o.Next)
239
/// Gets the <see cref="JToken"/> with the specified key.
241
/// <value>The <see cref="JToken"/> with the specified key.</value>
242
public virtual JToken this[object key]
244
get { throw new InvalidOperationException("Cannot access child value on {0}.".FormatWith(CultureInfo.InvariantCulture, GetType())); }
245
set { throw new InvalidOperationException("Cannot set child value on {0}.".FormatWith(CultureInfo.InvariantCulture, GetType())); }
249
/// Gets the <see cref="JToken"/> with the specified key converted to the specified type.
251
/// <typeparam name="T">The type to convert the token to.</typeparam>
252
/// <param name="key">The token key.</param>
253
/// <returns>The converted token value.</returns>
254
public virtual T Value<T>(object key)
256
JToken token = this[key];
258
return Extensions.Convert<JToken, T>(token);
262
/// Get the first child token of this token.
264
/// <value>A <see cref="JToken"/> containing the first child token of the <see cref="JToken"/>.</value>
265
public virtual JToken First
267
get { throw new InvalidOperationException("Cannot access child value on {0}.".FormatWith(CultureInfo.InvariantCulture, GetType())); }
271
/// Get the last child token of this token.
273
/// <value>A <see cref="JToken"/> containing the last child token of the <see cref="JToken"/>.</value>
274
public virtual JToken Last
276
get { throw new InvalidOperationException("Cannot access child value on {0}.".FormatWith(CultureInfo.InvariantCulture, GetType())); }
280
/// Returns a collection of the child tokens of this token, in document order.
282
/// <returns>An <see cref="IEnumerable{T}"/> of <see cref="JToken"/> containing the child tokens of this <see cref="JToken"/>, in document order.</returns>
283
public virtual JEnumerable<JToken> Children()
285
return JEnumerable<JToken>.Empty;
289
/// Returns a collection of the child tokens of this token, in document order, filtered by the specified type.
291
/// <typeparam name="T">The type to filter the child tokens on.</typeparam>
292
/// <returns>A <see cref="JEnumerable{T}"/> containing the child tokens of this <see cref="JToken"/>, in document order.</returns>
293
public JEnumerable<T> Children<T>() where T : JToken
295
return new JEnumerable<T>(Children().OfType<T>());
299
/// Returns a collection of the child values of this token, in document order.
301
/// <typeparam name="T">The type to convert the values to.</typeparam>
302
/// <returns>A <see cref="IEnumerable{T}"/> containing the child values of this <see cref="JToken"/>, in document order.</returns>
303
public virtual IEnumerable<T> Values<T>()
305
throw new InvalidOperationException("Cannot access child value on {0}.".FormatWith(CultureInfo.InvariantCulture, GetType()));
309
/// Removes this token from its parent.
314
throw new InvalidOperationException("The parent is missing.");
316
_parent.RemoveItem(this);
320
/// Replaces this token with the specified token.
322
/// <param name="value">The value.</param>
323
public void Replace(JToken value)
326
throw new InvalidOperationException("The parent is missing.");
328
_parent.ReplaceItem(this, value);
332
/// Writes this token to a <see cref="JsonWriter"/>.
334
/// <param name="writer">A <see cref="JsonWriter"/> into which this method will write.</param>
335
/// <param name="converters">A collection of <see cref="JsonConverter"/> which will be used when writing the token.</param>
336
public abstract void WriteTo(JsonWriter writer, params JsonConverter[] converters);
339
/// Returns the indented JSON for this token.
342
/// The indented JSON for this token.
344
public override string ToString()
346
return ToString(Formatting.Indented);
350
/// Returns the JSON for this token using the given formatting and converters.
352
/// <param name="formatting">Indicates how the output is formatted.</param>
353
/// <param name="converters">A collection of <see cref="JsonConverter"/> which will be used when writing the token.</param>
354
/// <returns>The JSON for this token using the given formatting and converters.</returns>
355
public string ToString(Formatting formatting, params JsonConverter[] converters)
357
using (StringWriter sw = new StringWriter(CultureInfo.InvariantCulture))
359
JsonTextWriter jw = new JsonTextWriter(sw);
360
jw.Formatting = formatting;
362
WriteTo(jw, converters);
364
return sw.ToString();
368
private static JValue EnsureValue(JToken value)
371
throw new ArgumentNullException("value");
373
if (value is JProperty)
374
value = ((JProperty)value).Value;
376
JValue v = value as JValue;
381
private static string GetType(JToken token)
383
ValidationUtils.ArgumentNotNull(token, "token");
385
if (token is JProperty)
386
token = ((JProperty)token).Value;
388
return token.Type.ToString();
391
private static bool ValidateToken(JToken o, JTokenType[] validTypes, bool nullable)
393
return (Array.IndexOf(validTypes, o.Type) != -1) || (nullable && (o.Type == JTokenType.Null || o.Type == JTokenType.Undefined));
396
#region Cast from operators
398
/// Performs an explicit conversion from <see cref="Newtonsoft.Json.Linq.JToken"/> to <see cref="System.Boolean"/>.
400
/// <param name="value">The value.</param>
401
/// <returns>The result of the conversion.</returns>
402
public static explicit operator bool(JToken value)
404
JValue v = EnsureValue(value);
405
if (v == null || !ValidateToken(v, BooleanTypes, false))
406
throw new ArgumentException("Can not convert {0} to Boolean.".FormatWith(CultureInfo.InvariantCulture, GetType(value)));
408
return Convert.ToBoolean(v.Value, CultureInfo.InvariantCulture);
411
#if !PocketPC && !NET20
413
/// Performs an explicit conversion from <see cref="Newtonsoft.Json.Linq.JToken"/> to <see cref="System.DateTimeOffset"/>.
415
/// <param name="value">The value.</param>
416
/// <returns>The result of the conversion.</returns>
417
public static explicit operator DateTimeOffset(JToken value)
419
JValue v = EnsureValue(value);
420
if (v == null || !ValidateToken(v, DateTimeTypes, false))
421
throw new ArgumentException("Can not convert {0} to DateTimeOffset.".FormatWith(CultureInfo.InvariantCulture, GetType(value)));
423
if (v.Value is DateTimeOffset)
424
return (DateTimeOffset)v.Value;
425
if (v.Value is string)
426
return DateTimeOffset.Parse((string)v.Value);
427
return new DateTimeOffset(Convert.ToDateTime(v.Value, CultureInfo.InvariantCulture));
432
/// Performs an explicit conversion from <see cref="Newtonsoft.Json.Linq.JToken"/> to <see cref="Nullable{Boolean}"/>.
434
/// <param name="value">The value.</param>
435
/// <returns>The result of the conversion.</returns>
436
public static explicit operator bool?(JToken value)
441
JValue v = EnsureValue(value);
442
if (v == null || !ValidateToken(v, BooleanTypes, true))
443
throw new ArgumentException("Can not convert {0} to Boolean.".FormatWith(CultureInfo.InvariantCulture, GetType(value)));
445
return (v.Value != null) ? (bool?)Convert.ToBoolean(v.Value, CultureInfo.InvariantCulture) : null;
449
/// Performs an explicit conversion from <see cref="Newtonsoft.Json.Linq.JToken"/> to <see cref="System.Int64"/>.
451
/// <param name="value">The value.</param>
452
/// <returns>The result of the conversion.</returns>
453
public static explicit operator long(JToken value)
455
JValue v = EnsureValue(value);
456
if (v == null || !ValidateToken(v, NumberTypes, false))
457
throw new ArgumentException("Can not convert {0} to Int64.".FormatWith(CultureInfo.InvariantCulture, GetType(value)));
459
return Convert.ToInt64(v.Value, CultureInfo.InvariantCulture);
463
/// Performs an explicit conversion from <see cref="Newtonsoft.Json.Linq.JToken"/> to <see cref="Nullable{DateTime}"/>.
465
/// <param name="value">The value.</param>
466
/// <returns>The result of the conversion.</returns>
467
public static explicit operator DateTime?(JToken value)
472
JValue v = EnsureValue(value);
473
if (v == null || !ValidateToken(v, DateTimeTypes, true))
474
throw new ArgumentException("Can not convert {0} to DateTime.".FormatWith(CultureInfo.InvariantCulture, GetType(value)));
476
return (v.Value != null) ? (DateTime?)Convert.ToDateTime(v.Value, CultureInfo.InvariantCulture) : null;
479
#if !PocketPC && !NET20
481
/// Performs an explicit conversion from <see cref="Newtonsoft.Json.Linq.JToken"/> to <see cref="Nullable{DateTimeOffset}"/>.
483
/// <param name="value">The value.</param>
484
/// <returns>The result of the conversion.</returns>
485
public static explicit operator DateTimeOffset?(JToken value)
490
JValue v = EnsureValue(value);
491
if (v == null || !ValidateToken(v, DateTimeTypes, true))
492
throw new ArgumentException("Can not convert {0} to DateTimeOffset.".FormatWith(CultureInfo.InvariantCulture, GetType(value)));
496
if (v.Value is DateTimeOffset)
497
return (DateTimeOffset?)v.Value;
498
if (v.Value is string)
499
return DateTimeOffset.Parse((string)v.Value);
500
return new DateTimeOffset(Convert.ToDateTime(v.Value, CultureInfo.InvariantCulture));
505
/// Performs an explicit conversion from <see cref="Newtonsoft.Json.Linq.JToken"/> to <see cref="Nullable{Decimal}"/>.
507
/// <param name="value">The value.</param>
508
/// <returns>The result of the conversion.</returns>
509
public static explicit operator decimal?(JToken value)
514
JValue v = EnsureValue(value);
515
if (v == null || !ValidateToken(v, NumberTypes, true))
516
throw new ArgumentException("Can not convert {0} to Decimal.".FormatWith(CultureInfo.InvariantCulture, GetType(value)));
518
return (v.Value != null) ? (decimal?)Convert.ToDecimal(v.Value, CultureInfo.InvariantCulture) : null;
522
/// Performs an explicit conversion from <see cref="Newtonsoft.Json.Linq.JToken"/> to <see cref="Nullable{Double}"/>.
524
/// <param name="value">The value.</param>
525
/// <returns>The result of the conversion.</returns>
526
public static explicit operator double?(JToken value)
531
JValue v = EnsureValue(value);
532
if (v == null || !ValidateToken(v, NumberTypes, true))
533
throw new ArgumentException("Can not convert {0} to Double.".FormatWith(CultureInfo.InvariantCulture, GetType(value)));
535
return (v.Value != null) ? (double?)Convert.ToDouble(v.Value, CultureInfo.InvariantCulture) : null;
539
/// Performs an explicit conversion from <see cref="Newtonsoft.Json.Linq.JToken"/> to <see cref="Nullable{Char}"/>.
541
/// <param name="value">The value.</param>
542
/// <returns>The result of the conversion.</returns>
543
public static explicit operator char?(JToken value)
548
JValue v = EnsureValue(value);
549
if (v == null || !ValidateToken(v, CharTypes, true))
550
throw new ArgumentException("Can not convert {0} to Char.".FormatWith(CultureInfo.InvariantCulture, GetType(value)));
552
return (v.Value != null) ? (char?)Convert.ToChar(v.Value, CultureInfo.InvariantCulture) : null;
556
/// Performs an explicit conversion from <see cref="Newtonsoft.Json.Linq.JToken"/> to <see cref="System.Int32"/>.
558
/// <param name="value">The value.</param>
559
/// <returns>The result of the conversion.</returns>
560
public static explicit operator int(JToken value)
562
JValue v = EnsureValue(value);
563
if (v == null || !ValidateToken(v, NumberTypes, false))
564
throw new ArgumentException("Can not convert {0} to Int32.".FormatWith(CultureInfo.InvariantCulture, GetType(value)));
566
return Convert.ToInt32(v.Value, CultureInfo.InvariantCulture);
570
/// Performs an explicit conversion from <see cref="Newtonsoft.Json.Linq.JToken"/> to <see cref="System.Int16"/>.
572
/// <param name="value">The value.</param>
573
/// <returns>The result of the conversion.</returns>
574
public static explicit operator short(JToken value)
576
JValue v = EnsureValue(value);
577
if (v == null || !ValidateToken(v, NumberTypes, false))
578
throw new ArgumentException("Can not convert {0} to Int16.".FormatWith(CultureInfo.InvariantCulture, GetType(value)));
580
return Convert.ToInt16(v.Value, CultureInfo.InvariantCulture);
584
/// Performs an explicit conversion from <see cref="Newtonsoft.Json.Linq.JToken"/> to <see cref="System.UInt16"/>.
586
/// <param name="value">The value.</param>
587
/// <returns>The result of the conversion.</returns>
588
[CLSCompliant(false)]
589
public static explicit operator ushort(JToken value)
591
JValue v = EnsureValue(value);
592
if (v == null || !ValidateToken(v, NumberTypes, false))
593
throw new ArgumentException("Can not convert {0} to UInt16.".FormatWith(CultureInfo.InvariantCulture, GetType(value)));
595
return Convert.ToUInt16(v.Value, CultureInfo.InvariantCulture);
599
/// Performs an explicit conversion from <see cref="Newtonsoft.Json.Linq.JToken"/> to <see cref="System.Char"/>.
601
/// <param name="value">The value.</param>
602
/// <returns>The result of the conversion.</returns>
603
[CLSCompliant(false)]
604
public static explicit operator char(JToken value)
606
JValue v = EnsureValue(value);
607
if (v == null || !ValidateToken(v, CharTypes, false))
608
throw new ArgumentException("Can not convert {0} to Char.".FormatWith(CultureInfo.InvariantCulture, GetType(value)));
610
return Convert.ToChar(v.Value, CultureInfo.InvariantCulture);
614
/// Performs an explicit conversion from <see cref="Newtonsoft.Json.Linq.JToken"/> to <see cref="System.Byte"/>.
616
/// <param name="value">The value.</param>
617
/// <returns>The result of the conversion.</returns>
618
public static explicit operator byte(JToken value)
620
JValue v = EnsureValue(value);
621
if (v == null || !ValidateToken(v, NumberTypes, false))
622
throw new ArgumentException("Can not convert {0} to Byte.".FormatWith(CultureInfo.InvariantCulture, GetType(value)));
624
return Convert.ToByte(v.Value, CultureInfo.InvariantCulture);
628
/// Performs an explicit conversion from <see cref="Newtonsoft.Json.Linq.JToken"/> to <see cref="Nullable{Int32}"/>.
630
/// <param name="value">The value.</param>
631
/// <returns>The result of the conversion.</returns>
632
public static explicit operator int?(JToken value)
637
JValue v = EnsureValue(value);
638
if (v == null || !ValidateToken(v, NumberTypes, true))
639
throw new ArgumentException("Can not convert {0} to Int32.".FormatWith(CultureInfo.InvariantCulture, GetType(value)));
641
return (v.Value != null) ? (int?)Convert.ToInt32(v.Value, CultureInfo.InvariantCulture) : null;
645
/// Performs an explicit conversion from <see cref="Newtonsoft.Json.Linq.JToken"/> to <see cref="Nullable{Int16}"/>.
647
/// <param name="value">The value.</param>
648
/// <returns>The result of the conversion.</returns>
649
public static explicit operator short?(JToken value)
654
JValue v = EnsureValue(value);
655
if (v == null || !ValidateToken(v, NumberTypes, true))
656
throw new ArgumentException("Can not convert {0} to Int16.".FormatWith(CultureInfo.InvariantCulture, GetType(value)));
658
return (v.Value != null) ? (short?)Convert.ToInt16(v.Value, CultureInfo.InvariantCulture) : null;
662
/// Performs an explicit conversion from <see cref="Newtonsoft.Json.Linq.JToken"/> to <see cref="Nullable{UInt16}"/>.
664
/// <param name="value">The value.</param>
665
/// <returns>The result of the conversion.</returns>
666
[CLSCompliant(false)]
667
public static explicit operator ushort?(JToken value)
672
JValue v = EnsureValue(value);
673
if (v == null || !ValidateToken(v, NumberTypes, true))
674
throw new ArgumentException("Can not convert {0} to UInt16.".FormatWith(CultureInfo.InvariantCulture, GetType(value)));
676
return (v.Value != null) ? (ushort?)Convert.ToUInt16(v.Value, CultureInfo.InvariantCulture) : null;
680
/// Performs an explicit conversion from <see cref="Newtonsoft.Json.Linq.JToken"/> to <see cref="Nullable{Byte}"/>.
682
/// <param name="value">The value.</param>
683
/// <returns>The result of the conversion.</returns>
684
public static explicit operator byte?(JToken value)
689
JValue v = EnsureValue(value);
690
if (v == null || !ValidateToken(v, NumberTypes, true))
691
throw new ArgumentException("Can not convert {0} to Byte.".FormatWith(CultureInfo.InvariantCulture, GetType(value)));
693
return (v.Value != null) ? (byte?)Convert.ToByte(v.Value, CultureInfo.InvariantCulture) : null;
697
/// Performs an explicit conversion from <see cref="Newtonsoft.Json.Linq.JToken"/> to <see cref="System.DateTime"/>.
699
/// <param name="value">The value.</param>
700
/// <returns>The result of the conversion.</returns>
701
public static explicit operator DateTime(JToken value)
703
JValue v = EnsureValue(value);
704
if (v == null || !ValidateToken(v, DateTimeTypes, false))
705
throw new ArgumentException("Can not convert {0} to DateTime.".FormatWith(CultureInfo.InvariantCulture, GetType(value)));
707
return Convert.ToDateTime(v.Value, CultureInfo.InvariantCulture);
711
/// Performs an explicit conversion from <see cref="Newtonsoft.Json.Linq.JToken"/> to <see cref="Nullable{Int64}"/>.
713
/// <param name="value">The value.</param>
714
/// <returns>The result of the conversion.</returns>
715
public static explicit operator long?(JToken value)
720
JValue v = EnsureValue(value);
721
if (v == null || !ValidateToken(v, NumberTypes, true))
722
throw new ArgumentException("Can not convert {0} to Int64.".FormatWith(CultureInfo.InvariantCulture, GetType(value)));
724
return (v.Value != null) ? (long?)Convert.ToInt64(v.Value, CultureInfo.InvariantCulture) : null;
728
/// Performs an explicit conversion from <see cref="Newtonsoft.Json.Linq.JToken"/> to <see cref="Nullable{Single}"/>.
730
/// <param name="value">The value.</param>
731
/// <returns>The result of the conversion.</returns>
732
public static explicit operator float?(JToken value)
737
JValue v = EnsureValue(value);
738
if (v == null || !ValidateToken(v, NumberTypes, true))
739
throw new ArgumentException("Can not convert {0} to Single.".FormatWith(CultureInfo.InvariantCulture, GetType(value)));
741
return (v.Value != null) ? (float?)Convert.ToSingle(v.Value, CultureInfo.InvariantCulture) : null;
745
/// Performs an explicit conversion from <see cref="Newtonsoft.Json.Linq.JToken"/> to <see cref="System.Decimal"/>.
747
/// <param name="value">The value.</param>
748
/// <returns>The result of the conversion.</returns>
749
public static explicit operator decimal(JToken value)
751
JValue v = EnsureValue(value);
752
if (v == null || !ValidateToken(v, NumberTypes, false))
753
throw new ArgumentException("Can not convert {0} to Decimal.".FormatWith(CultureInfo.InvariantCulture, GetType(value)));
755
return Convert.ToDecimal(v.Value, CultureInfo.InvariantCulture);
759
/// Performs an explicit conversion from <see cref="Newtonsoft.Json.Linq.JToken"/> to <see cref="Nullable{UInt32}"/>.
761
/// <param name="value">The value.</param>
762
/// <returns>The result of the conversion.</returns>
763
[CLSCompliant(false)]
764
public static explicit operator uint?(JToken value)
769
JValue v = EnsureValue(value);
770
if (v == null || !ValidateToken(v, NumberTypes, true))
771
throw new ArgumentException("Can not convert {0} to UInt32.".FormatWith(CultureInfo.InvariantCulture, GetType(value)));
773
return (v.Value != null) ? (uint?)Convert.ToUInt32(v.Value, CultureInfo.InvariantCulture) : null;
777
/// Performs an explicit conversion from <see cref="Newtonsoft.Json.Linq.JToken"/> to <see cref="Nullable{UInt64}"/>.
779
/// <param name="value">The value.</param>
780
/// <returns>The result of the conversion.</returns>
781
[CLSCompliant(false)]
782
public static explicit operator ulong?(JToken value)
787
JValue v = EnsureValue(value);
788
if (v == null || !ValidateToken(v, NumberTypes, true))
789
throw new ArgumentException("Can not convert {0} to UInt64.".FormatWith(CultureInfo.InvariantCulture, GetType(value)));
791
return (v.Value != null) ? (ulong?)Convert.ToUInt64(v.Value, CultureInfo.InvariantCulture) : null;
795
/// Performs an explicit conversion from <see cref="Newtonsoft.Json.Linq.JToken"/> to <see cref="System.Double"/>.
797
/// <param name="value">The value.</param>
798
/// <returns>The result of the conversion.</returns>
799
public static explicit operator double(JToken value)
801
JValue v = EnsureValue(value);
802
if (v == null || !ValidateToken(v, NumberTypes, false))
803
throw new ArgumentException("Can not convert {0} to Double.".FormatWith(CultureInfo.InvariantCulture, GetType(value)));
805
return Convert.ToDouble(v.Value, CultureInfo.InvariantCulture);
809
/// Performs an explicit conversion from <see cref="Newtonsoft.Json.Linq.JToken"/> to <see cref="System.Single"/>.
811
/// <param name="value">The value.</param>
812
/// <returns>The result of the conversion.</returns>
813
public static explicit operator float(JToken value)
815
JValue v = EnsureValue(value);
816
if (v == null || !ValidateToken(v, NumberTypes, false))
817
throw new ArgumentException("Can not convert {0} to Single.".FormatWith(CultureInfo.InvariantCulture, GetType(value)));
819
return Convert.ToSingle(v.Value, CultureInfo.InvariantCulture);
823
/// Performs an explicit conversion from <see cref="Newtonsoft.Json.Linq.JToken"/> to <see cref="System.String"/>.
825
/// <param name="value">The value.</param>
826
/// <returns>The result of the conversion.</returns>
827
public static explicit operator string(JToken value)
832
JValue v = EnsureValue(value);
833
if (v == null || !ValidateToken(v, StringTypes, true))
834
throw new ArgumentException("Can not convert {0} to String.".FormatWith(CultureInfo.InvariantCulture, GetType(value)));
838
if (v.Value is byte[])
839
return Convert.ToBase64String((byte[]) v.Value);
841
return Convert.ToString(v.Value, CultureInfo.InvariantCulture);
845
/// Performs an explicit conversion from <see cref="Newtonsoft.Json.Linq.JToken"/> to <see cref="System.UInt32"/>.
847
/// <param name="value">The value.</param>
848
/// <returns>The result of the conversion.</returns>
849
[CLSCompliant(false)]
850
public static explicit operator uint(JToken value)
852
JValue v = EnsureValue(value);
853
if (v == null || !ValidateToken(v, NumberTypes, false))
854
throw new ArgumentException("Can not convert {0} to UInt32.".FormatWith(CultureInfo.InvariantCulture, GetType(value)));
856
return Convert.ToUInt32(v.Value, CultureInfo.InvariantCulture);
860
/// Performs an explicit conversion from <see cref="Newtonsoft.Json.Linq.JToken"/> to <see cref="System.UInt64"/>.
862
/// <param name="value">The value.</param>
863
/// <returns>The result of the conversion.</returns>
864
[CLSCompliant(false)]
865
public static explicit operator ulong(JToken value)
867
JValue v = EnsureValue(value);
868
if (v == null || !ValidateToken(v, NumberTypes, false))
869
throw new ArgumentException("Can not convert {0} to UInt64.".FormatWith(CultureInfo.InvariantCulture, GetType(value)));
871
return Convert.ToUInt64(v.Value, CultureInfo.InvariantCulture);
875
/// Performs an explicit conversion from <see cref="Newtonsoft.Json.Linq.JToken"/> to <see cref="T:System.Byte[]"/>.
877
/// <param name="value">The value.</param>
878
/// <returns>The result of the conversion.</returns>
879
public static explicit operator byte[](JToken value)
884
JValue v = EnsureValue(value);
885
if (v == null || !ValidateToken(v, BytesTypes, false))
886
throw new ArgumentException("Can not convert {0} to byte array.".FormatWith(CultureInfo.InvariantCulture, GetType(value)));
888
if (v.Value is string)
889
return Convert.FromBase64String(Convert.ToString(v.Value, CultureInfo.InvariantCulture));
890
return (byte[])v.Value;
894
/// Performs an explicit conversion from <see cref="Newtonsoft.Json.Linq.JToken"/> to <see cref="System.Guid"/>.
896
/// <param name="value">The value.</param>
897
/// <returns>The result of the conversion.</returns>
898
public static explicit operator Guid(JToken value)
900
JValue v = EnsureValue(value);
901
if (v == null || !ValidateToken(v, GuidTypes, false))
902
throw new ArgumentException("Can not convert {0} to Guid.".FormatWith(CultureInfo.InvariantCulture, GetType(value)));
904
return (v.Value is Guid) ? (Guid)v.Value : new Guid(Convert.ToString(v.Value, CultureInfo.InvariantCulture));
908
/// Performs an explicit conversion from <see cref="Newtonsoft.Json.Linq.JToken"/> to <see cref="System.Guid"/>.
910
/// <param name="value">The value.</param>
911
/// <returns>The result of the conversion.</returns>
912
public static explicit operator Guid?(JToken value)
917
JValue v = EnsureValue(value);
918
if (v == null || !ValidateToken(v, GuidTypes, true))
919
throw new ArgumentException("Can not convert {0} to Guid.".FormatWith(CultureInfo.InvariantCulture, GetType(value)));
924
return (v.Value is Guid) ? (Guid)v.Value : new Guid(Convert.ToString(v.Value, CultureInfo.InvariantCulture));
928
/// Performs an explicit conversion from <see cref="Newtonsoft.Json.Linq.JToken"/> to <see cref="System.TimeSpan"/>.
930
/// <param name="value">The value.</param>
931
/// <returns>The result of the conversion.</returns>
932
public static explicit operator TimeSpan(JToken value)
934
JValue v = EnsureValue(value);
935
if (v == null || !ValidateToken(v, TimeSpanTypes, false))
936
throw new ArgumentException("Can not convert {0} to TimeSpan.".FormatWith(CultureInfo.InvariantCulture, GetType(value)));
938
return (v.Value is TimeSpan) ? (TimeSpan)v.Value : ConvertUtils.ParseTimeSpan(Convert.ToString(v.Value, CultureInfo.InvariantCulture));
942
/// Performs an explicit conversion from <see cref="Newtonsoft.Json.Linq.JToken"/> to <see cref="System.TimeSpan"/>.
944
/// <param name="value">The value.</param>
945
/// <returns>The result of the conversion.</returns>
946
public static explicit operator TimeSpan?(JToken value)
951
JValue v = EnsureValue(value);
952
if (v == null || !ValidateToken(v, TimeSpanTypes, true))
953
throw new ArgumentException("Can not convert {0} to TimeSpan.".FormatWith(CultureInfo.InvariantCulture, GetType(value)));
958
return (v.Value is TimeSpan) ? (TimeSpan)v.Value : ConvertUtils.ParseTimeSpan(Convert.ToString(v.Value, CultureInfo.InvariantCulture));
962
/// Performs an explicit conversion from <see cref="Newtonsoft.Json.Linq.JToken"/> to <see cref="System.Uri"/>.
964
/// <param name="value">The value.</param>
965
/// <returns>The result of the conversion.</returns>
966
public static explicit operator Uri(JToken value)
971
JValue v = EnsureValue(value);
972
if (v == null || !ValidateToken(v, UriTypes, true))
973
throw new ArgumentException("Can not convert {0} to Uri.".FormatWith(CultureInfo.InvariantCulture, GetType(value)));
978
return (v.Value is Uri) ? (Uri)v.Value : new Uri(Convert.ToString(v.Value, CultureInfo.InvariantCulture));
982
#region Cast to operators
984
/// Performs an implicit conversion from <see cref="Boolean"/> to <see cref="JToken"/>.
986
/// <param name="value">The value to create a <see cref="JValue"/> from.</param>
987
/// <returns>The <see cref="JValue"/> initialized with the specified value.</returns>
988
public static implicit operator JToken(bool value)
990
return new JValue(value);
993
#if !PocketPC && !NET20
995
/// Performs an implicit conversion from <see cref="DateTimeOffset"/> to <see cref="JToken"/>.
997
/// <param name="value">The value to create a <see cref="JValue"/> from.</param>
998
/// <returns>The <see cref="JValue"/> initialized with the specified value.</returns>
999
public static implicit operator JToken(DateTimeOffset value)
1001
return new JValue(value);
1006
/// Performs an implicit conversion from <see cref="Nullable{Boolean}"/> to <see cref="JToken"/>.
1008
/// <param name="value">The value to create a <see cref="JValue"/> from.</param>
1009
/// <returns>The <see cref="JValue"/> initialized with the specified value.</returns>
1010
public static implicit operator JToken(bool? value)
1012
return new JValue(value);
1016
/// Performs an implicit conversion from <see cref="Nullable{Int64}"/> to <see cref="JToken"/>.
1018
/// <param name="value">The value to create a <see cref="JValue"/> from.</param>
1019
/// <returns>The <see cref="JValue"/> initialized with the specified value.</returns>
1020
public static implicit operator JToken(long value)
1022
return new JValue(value);
1026
/// Performs an implicit conversion from <see cref="Nullable{DateTime}"/> to <see cref="JToken"/>.
1028
/// <param name="value">The value to create a <see cref="JValue"/> from.</param>
1029
/// <returns>The <see cref="JValue"/> initialized with the specified value.</returns>
1030
public static implicit operator JToken(DateTime? value)
1032
return new JValue(value);
1035
#if !PocketPC && !NET20
1037
/// Performs an implicit conversion from <see cref="Nullable{DateTimeOffset}"/> to <see cref="JToken"/>.
1039
/// <param name="value">The value to create a <see cref="JValue"/> from.</param>
1040
/// <returns>The <see cref="JValue"/> initialized with the specified value.</returns>
1041
public static implicit operator JToken(DateTimeOffset? value)
1043
return new JValue(value);
1048
/// Performs an implicit conversion from <see cref="Nullable{Decimal}"/> to <see cref="JToken"/>.
1050
/// <param name="value">The value to create a <see cref="JValue"/> from.</param>
1051
/// <returns>The <see cref="JValue"/> initialized with the specified value.</returns>
1052
public static implicit operator JToken(decimal? value)
1054
return new JValue(value);
1058
/// Performs an implicit conversion from <see cref="Nullable{Double}"/> to <see cref="JToken"/>.
1060
/// <param name="value">The value to create a <see cref="JValue"/> from.</param>
1061
/// <returns>The <see cref="JValue"/> initialized with the specified value.</returns>
1062
public static implicit operator JToken(double? value)
1064
return new JValue(value);
1068
/// Performs an implicit conversion from <see cref="Int16"/> to <see cref="JToken"/>.
1070
/// <param name="value">The value to create a <see cref="JValue"/> from.</param>
1071
/// <returns>The <see cref="JValue"/> initialized with the specified value.</returns>
1072
[CLSCompliant(false)]
1073
public static implicit operator JToken(short value)
1075
return new JValue(value);
1079
/// Performs an implicit conversion from <see cref="UInt16"/> to <see cref="JToken"/>.
1081
/// <param name="value">The value to create a <see cref="JValue"/> from.</param>
1082
/// <returns>The <see cref="JValue"/> initialized with the specified value.</returns>
1083
[CLSCompliant(false)]
1084
public static implicit operator JToken(ushort value)
1086
return new JValue(value);
1090
/// Performs an implicit conversion from <see cref="Int32"/> to <see cref="JToken"/>.
1092
/// <param name="value">The value to create a <see cref="JValue"/> from.</param>
1093
/// <returns>The <see cref="JValue"/> initialized with the specified value.</returns>
1094
public static implicit operator JToken(int value)
1096
return new JValue(value);
1100
/// Performs an implicit conversion from <see cref="Nullable{Int32}"/> to <see cref="JToken"/>.
1102
/// <param name="value">The value to create a <see cref="JValue"/> from.</param>
1103
/// <returns>The <see cref="JValue"/> initialized with the specified value.</returns>
1104
public static implicit operator JToken(int? value)
1106
return new JValue(value);
1110
/// Performs an implicit conversion from <see cref="DateTime"/> to <see cref="JToken"/>.
1112
/// <param name="value">The value to create a <see cref="JValue"/> from.</param>
1113
/// <returns>The <see cref="JValue"/> initialized with the specified value.</returns>
1114
public static implicit operator JToken(DateTime value)
1116
return new JValue(value);
1120
/// Performs an implicit conversion from <see cref="Nullable{Int64}"/> to <see cref="JToken"/>.
1122
/// <param name="value">The value to create a <see cref="JValue"/> from.</param>
1123
/// <returns>The <see cref="JValue"/> initialized with the specified value.</returns>
1124
public static implicit operator JToken(long? value)
1126
return new JValue(value);
1130
/// Performs an implicit conversion from <see cref="Nullable{Single}"/> to <see cref="JToken"/>.
1132
/// <param name="value">The value to create a <see cref="JValue"/> from.</param>
1133
/// <returns>The <see cref="JValue"/> initialized with the specified value.</returns>
1134
public static implicit operator JToken(float? value)
1136
return new JValue(value);
1140
/// Performs an implicit conversion from <see cref="Decimal"/> to <see cref="JToken"/>.
1142
/// <param name="value">The value to create a <see cref="JValue"/> from.</param>
1143
/// <returns>The <see cref="JValue"/> initialized with the specified value.</returns>
1144
public static implicit operator JToken(decimal value)
1146
return new JValue(value);
1150
/// Performs an implicit conversion from <see cref="Nullable{Int16}"/> to <see cref="JToken"/>.
1152
/// <param name="value">The value to create a <see cref="JValue"/> from.</param>
1153
/// <returns>The <see cref="JValue"/> initialized with the specified value.</returns>
1154
[CLSCompliant(false)]
1155
public static implicit operator JToken(short? value)
1157
return new JValue(value);
1161
/// Performs an implicit conversion from <see cref="Nullable{UInt16}"/> to <see cref="JToken"/>.
1163
/// <param name="value">The value to create a <see cref="JValue"/> from.</param>
1164
/// <returns>The <see cref="JValue"/> initialized with the specified value.</returns>
1165
[CLSCompliant(false)]
1166
public static implicit operator JToken(ushort? value)
1168
return new JValue(value);
1172
/// Performs an implicit conversion from <see cref="Nullable{UInt32}"/> to <see cref="JToken"/>.
1174
/// <param name="value">The value to create a <see cref="JValue"/> from.</param>
1175
/// <returns>The <see cref="JValue"/> initialized with the specified value.</returns>
1176
[CLSCompliant(false)]
1177
public static implicit operator JToken(uint? value)
1179
return new JValue(value);
1183
/// Performs an implicit conversion from <see cref="Nullable{UInt64}"/> to <see cref="JToken"/>.
1185
/// <param name="value">The value to create a <see cref="JValue"/> from.</param>
1186
/// <returns>The <see cref="JValue"/> initialized with the specified value.</returns>
1187
[CLSCompliant(false)]
1188
public static implicit operator JToken(ulong? value)
1190
return new JValue(value);
1194
/// Performs an implicit conversion from <see cref="Double"/> to <see cref="JToken"/>.
1196
/// <param name="value">The value to create a <see cref="JValue"/> from.</param>
1197
/// <returns>The <see cref="JValue"/> initialized with the specified value.</returns>
1198
public static implicit operator JToken(double value)
1200
return new JValue(value);
1204
/// Performs an implicit conversion from <see cref="Single"/> to <see cref="JToken"/>.
1206
/// <param name="value">The value to create a <see cref="JValue"/> from.</param>
1207
/// <returns>The <see cref="JValue"/> initialized with the specified value.</returns>
1208
public static implicit operator JToken(float value)
1210
return new JValue(value);
1214
/// Performs an implicit conversion from <see cref="String"/> to <see cref="JToken"/>.
1216
/// <param name="value">The value to create a <see cref="JValue"/> from.</param>
1217
/// <returns>The <see cref="JValue"/> initialized with the specified value.</returns>
1218
public static implicit operator JToken(string value)
1220
return new JValue(value);
1224
/// Performs an implicit conversion from <see cref="UInt32"/> to <see cref="JToken"/>.
1226
/// <param name="value">The value to create a <see cref="JValue"/> from.</param>
1227
/// <returns>The <see cref="JValue"/> initialized with the specified value.</returns>
1228
[CLSCompliant(false)]
1229
public static implicit operator JToken(uint value)
1231
return new JValue(value);
1235
/// Performs an implicit conversion from <see cref="UInt64"/> to <see cref="JToken"/>.
1237
/// <param name="value">The value to create a <see cref="JValue"/> from.</param>
1238
/// <returns>The <see cref="JValue"/> initialized with the specified value.</returns>
1239
[CLSCompliant(false)]
1240
public static implicit operator JToken(ulong value)
1242
return new JValue(value);
1246
/// Performs an implicit conversion from <see cref="T:System.Byte[]"/> to <see cref="Newtonsoft.Json.Linq.JToken"/>.
1248
/// <param name="value">The value to create a <see cref="JValue"/> from.</param>
1249
/// <returns>The <see cref="JValue"/> initialized with the specified value.</returns>
1250
public static implicit operator JToken(byte[] value)
1252
return new JValue(value);
1256
/// Performs an implicit conversion from <see cref="T:System.Uri"/> to <see cref="Newtonsoft.Json.Linq.JToken"/>.
1258
/// <param name="value">The value to create a <see cref="JValue"/> from.</param>
1259
/// <returns>The <see cref="JValue"/> initialized with the specified value.</returns>
1260
public static implicit operator JToken(Uri value)
1262
return new JValue(value);
1266
/// Performs an implicit conversion from <see cref="T:System.TimeSpan"/> to <see cref="Newtonsoft.Json.Linq.JToken"/>.
1268
/// <param name="value">The value to create a <see cref="JValue"/> from.</param>
1269
/// <returns>The <see cref="JValue"/> initialized with the specified value.</returns>
1270
public static implicit operator JToken(TimeSpan value)
1272
return new JValue(value);
1276
/// Performs an implicit conversion from <see cref="Nullable{TimeSpan}"/> to <see cref="Newtonsoft.Json.Linq.JToken"/>.
1278
/// <param name="value">The value to create a <see cref="JValue"/> from.</param>
1279
/// <returns>The <see cref="JValue"/> initialized with the specified value.</returns>
1280
public static implicit operator JToken(TimeSpan? value)
1282
return new JValue(value);
1286
/// Performs an implicit conversion from <see cref="T:System.Guid"/> to <see cref="Newtonsoft.Json.Linq.JToken"/>.
1288
/// <param name="value">The value to create a <see cref="JValue"/> from.</param>
1289
/// <returns>The <see cref="JValue"/> initialized with the specified value.</returns>
1290
public static implicit operator JToken(Guid value)
1292
return new JValue(value);
1296
/// Performs an implicit conversion from <see cref="Nullable{Guid}"/> to <see cref="Newtonsoft.Json.Linq.JToken"/>.
1298
/// <param name="value">The value to create a <see cref="JValue"/> from.</param>
1299
/// <returns>The <see cref="JValue"/> initialized with the specified value.</returns>
1300
public static implicit operator JToken(Guid? value)
1302
return new JValue(value);
1306
IEnumerator IEnumerable.GetEnumerator()
1308
return ((IEnumerable<JToken>)this).GetEnumerator();
1311
IEnumerator<JToken> IEnumerable<JToken>.GetEnumerator()
1313
return Children().GetEnumerator();
1316
internal abstract int GetDeepHashCode();
1318
IJEnumerable<JToken> IJEnumerable<JToken>.this[object key]
1320
get { return this[key]; }
1324
/// Creates an <see cref="JsonReader"/> for this token.
1326
/// <returns>An <see cref="JsonReader"/> that can be used to read this token and its descendants.</returns>
1327
public JsonReader CreateReader()
1329
return new JTokenReader(this);
1332
internal static JToken FromObjectInternal(object o, JsonSerializer jsonSerializer)
1334
ValidationUtils.ArgumentNotNull(o, "o");
1335
ValidationUtils.ArgumentNotNull(jsonSerializer, "jsonSerializer");
1338
using (JTokenWriter jsonWriter = new JTokenWriter())
1340
jsonSerializer.Serialize(jsonWriter, o);
1341
token = jsonWriter.Token;
1348
/// Creates a <see cref="JToken"/> from an object.
1350
/// <param name="o">The object that will be used to create <see cref="JToken"/>.</param>
1351
/// <returns>A <see cref="JToken"/> with the value of the specified object</returns>
1352
public static JToken FromObject(object o)
1354
return FromObjectInternal(o, new JsonSerializer());
1358
/// Creates a <see cref="JToken"/> from an object using the specified <see cref="JsonSerializer"/>.
1360
/// <param name="o">The object that will be used to create <see cref="JToken"/>.</param>
1361
/// <param name="jsonSerializer">The <see cref="JsonSerializer"/> that will be used when reading the object.</param>
1362
/// <returns>A <see cref="JToken"/> with the value of the specified object</returns>
1363
public static JToken FromObject(object o, JsonSerializer jsonSerializer)
1365
return FromObjectInternal(o, jsonSerializer);
1369
/// Creates the specified .NET type from the <see cref="JToken"/>.
1371
/// <typeparam name="T">The object type that the token will be deserialized to.</typeparam>
1372
/// <returns>The new object created from the JSON value.</returns>
1373
public T ToObject<T>()
1375
return (T)ToObject(typeof(T));
1379
/// Creates the specified .NET type from the <see cref="JToken"/>.
1381
/// <param name="objectType">The object type that the token will be deserialized to.</param>
1382
/// <returns>The new object created from the JSON value.</returns>
1383
public object ToObject(Type objectType)
1385
return ToObject(objectType, false);
1388
private object ToObject(Type objectType, bool isNullable)
1390
TypeCode typeCode = ConvertUtils.GetTypeCode(objectType);
1394
case TypeCode.Object:
1395
if (!isNullable && ReflectionUtils.IsNullableType(objectType))
1396
return ToObject(Nullable.GetUnderlyingType(objectType), true);
1398
// fall back to standard JsonSerializer
1400
case TypeCode.Boolean:
1402
return (bool?) this;
1407
return (char?) this;
1410
case TypeCode.SByte:
1412
return (sbyte?) this;
1414
return (sbyte) this;
1417
return (byte?) this;
1420
case TypeCode.Int16:
1422
return (short?) this;
1424
return (short) this;
1425
case TypeCode.UInt16:
1427
return (ushort?) this;
1429
return (ushort) this;
1430
case TypeCode.Int32:
1435
case TypeCode.UInt32:
1437
return (uint?) this;
1440
case TypeCode.Int64:
1442
return (long?) this;
1445
case TypeCode.UInt64:
1447
return (ulong?) this;
1449
return (ulong) this;
1450
case TypeCode.Single:
1452
return (float?) this;
1454
return (float) this;
1455
case TypeCode.Double:
1457
return (double?) this;
1459
return (double) this;
1460
case TypeCode.Decimal:
1462
return (decimal?) this;
1464
return (decimal) this;
1465
case TypeCode.DateTime:
1467
return (DateTime?) this;
1469
return (DateTime) this;
1470
case TypeCode.String:
1471
return (string) this;
1474
#if !PocketPC && !NET20
1475
if (objectType == typeof (DateTimeOffset))
1478
return (DateTimeOffset?) this;
1480
return (DateTimeOffset) this;
1483
if (objectType == typeof (Guid))
1486
return (Guid?) this;
1490
if (objectType == typeof (Uri))
1494
if (objectType == typeof (TimeSpan))
1497
return (TimeSpan?) this;
1499
return (TimeSpan) this;
1502
return ToObject(objectType, new JsonSerializer());
1506
/// Creates the specified .NET type from the <see cref="JToken"/> using the specified <see cref="JsonSerializer"/>.
1508
/// <typeparam name="T">The object type that the token will be deserialized to.</typeparam>
1509
/// <param name="jsonSerializer">The <see cref="JsonSerializer"/> that will be used when creating the object.</param>
1510
/// <returns>The new object created from the JSON value.</returns>
1511
public T ToObject<T>(JsonSerializer jsonSerializer)
1513
return (T)ToObject(typeof(T), jsonSerializer);
1517
/// Creates the specified .NET type from the <see cref="JToken"/> using the specified <see cref="JsonSerializer"/>.
1519
/// <param name="objectType">The object type that the token will be deserialized to.</param>
1520
/// <param name="jsonSerializer">The <see cref="JsonSerializer"/> that will be used when creating the object.</param>
1521
/// <returns>The new object created from the JSON value.</returns>
1522
public object ToObject(Type objectType, JsonSerializer jsonSerializer)
1524
ValidationUtils.ArgumentNotNull(jsonSerializer, "jsonSerializer");
1526
using (JTokenReader jsonReader = new JTokenReader(this))
1528
return jsonSerializer.Deserialize(jsonReader, objectType);
1533
/// Creates a <see cref="JToken"/> from a <see cref="JsonReader"/>.
1535
/// <param name="reader">An <see cref="JsonReader"/> positioned at the token to read into this <see cref="JToken"/>.</param>
1537
/// An <see cref="JToken"/> that contains the token and its descendant tokens
1538
/// that were read from the reader. The runtime type of the token is determined
1539
/// by the token type of the first token encountered in the reader.
1541
public static JToken ReadFrom(JsonReader reader)
1543
ValidationUtils.ArgumentNotNull(reader, "reader");
1545
if (reader.TokenType == JsonToken.None)
1548
throw JsonReaderException.Create(reader, "Error reading JToken from JsonReader.");
1551
if (reader.TokenType == JsonToken.StartObject)
1552
return JObject.Load(reader);
1554
if (reader.TokenType == JsonToken.StartArray)
1555
return JArray.Load(reader);
1557
if (reader.TokenType == JsonToken.PropertyName)
1558
return JProperty.Load(reader);
1560
if (reader.TokenType == JsonToken.StartConstructor)
1561
return JConstructor.Load(reader);
1563
if (!JsonReader.IsStartToken(reader.TokenType))
1564
return new JValue(reader.Value);
1566
throw JsonReaderException.Create(reader, "Error reading JToken from JsonReader. Unexpected token: {0}".FormatWith(CultureInfo.InvariantCulture, reader.TokenType));
1570
/// Load a <see cref="JToken"/> from a string that contains JSON.
1572
/// <param name="json">A <see cref="String"/> that contains JSON.</param>
1573
/// <returns>A <see cref="JToken"/> populated from the string that contains JSON.</returns>
1574
public static JToken Parse(string json)
1576
JsonReader reader = new JsonTextReader(new StringReader(json));
1578
JToken t = Load(reader);
1580
if (reader.Read() && reader.TokenType != JsonToken.Comment)
1581
throw JsonReaderException.Create(reader, "Additional text found in JSON string after parsing content.");
1587
/// Creates a <see cref="JToken"/> from a <see cref="JsonReader"/>.
1589
/// <param name="reader">An <see cref="JsonReader"/> positioned at the token to read into this <see cref="JToken"/>.</param>
1591
/// An <see cref="JToken"/> that contains the token and its descendant tokens
1592
/// that were read from the reader. The runtime type of the token is determined
1593
/// by the token type of the first token encountered in the reader.
1595
public static JToken Load(JsonReader reader)
1597
return ReadFrom(reader);
1600
internal void SetLineInfo(IJsonLineInfo lineInfo)
1602
if (lineInfo == null || !lineInfo.HasLineInfo())
1605
SetLineInfo(lineInfo.LineNumber, lineInfo.LinePosition);
1608
internal void SetLineInfo(int lineNumber, int linePosition)
1610
_lineNumber = lineNumber;
1611
_linePosition = linePosition;
1614
bool IJsonLineInfo.HasLineInfo()
1616
return (_lineNumber != null && _linePosition != null);
1619
int IJsonLineInfo.LineNumber
1621
get { return _lineNumber ?? 0; }
1624
int IJsonLineInfo.LinePosition
1626
get { return _linePosition ?? 0; }
1630
/// Selects the token that matches the object path.
1632
/// <param name="path">
1633
/// The object path from the current <see cref="JToken"/> to the <see cref="JToken"/>
1634
/// to be returned. This must be a string of property names or array indexes separated
1635
/// by periods, such as <code>Tables[0].DefaultView[0].Price</code> in C# or
1636
/// <code>Tables(0).DefaultView(0).Price</code> in Visual Basic.
1638
/// <returns>The <see cref="JToken"/> that matches the object path or a null reference if no matching token is found.</returns>
1639
public JToken SelectToken(string path)
1641
return SelectToken(path, false);
1645
/// Selects the token that matches the object path.
1647
/// <param name="path">
1648
/// The object path from the current <see cref="JToken"/> to the <see cref="JToken"/>
1649
/// to be returned. This must be a string of property names or array indexes separated
1650
/// by periods, such as <code>Tables[0].DefaultView[0].Price</code> in C# or
1651
/// <code>Tables(0).DefaultView(0).Price</code> in Visual Basic.
1653
/// <param name="errorWhenNoMatch">A flag to indicate whether an error should be thrown if no token is found.</param>
1654
/// <returns>The <see cref="JToken"/> that matches the object path.</returns>
1655
public JToken SelectToken(string path, bool errorWhenNoMatch)
1657
JPath p = new JPath(path);
1658
return p.Evaluate(this, errorWhenNoMatch);
1661
#if !(NET35 || NET20 || WINDOWS_PHONE || PORTABLE)
1663
/// Returns the <see cref="T:System.Dynamic.DynamicMetaObject"/> responsible for binding operations performed on this object.
1665
/// <param name="parameter">The expression tree representation of the runtime value.</param>
1667
/// The <see cref="T:System.Dynamic.DynamicMetaObject"/> to bind this object.
1669
protected virtual DynamicMetaObject GetMetaObject(Expression parameter)
1671
return new DynamicProxyMetaObject<JToken>(parameter, this, new DynamicProxy<JToken>(), true);
1675
/// Returns the <see cref="T:System.Dynamic.DynamicMetaObject"/> responsible for binding operations performed on this object.
1677
/// <param name="parameter">The expression tree representation of the runtime value.</param>
1679
/// The <see cref="T:System.Dynamic.DynamicMetaObject"/> to bind this object.
1681
DynamicMetaObject IDynamicMetaObjectProvider.GetMetaObject(Expression parameter)
1683
return GetMetaObject(parameter);
1687
#if !(SILVERLIGHT || NETFX_CORE || PORTABLE)
1688
object ICloneable.Clone()
1695
/// Creates a new instance of the <see cref="JToken"/>. All child tokens are recursively cloned.
1697
/// <returns>A new instance of the <see cref="JToken"/>.</returns>
1698
public JToken DeepClone()
1700
return CloneToken();
b'\\ No newline at end of file'