<PackageReference Include="Newtonsoft.Json" Version="11.0.2" />

JObject

Represents a JSON object.
using Newtonsoft.Json.Utilities; using System; using System.Collections; using System.Collections.Generic; using System.Collections.Specialized; using System.ComponentModel; using System.Dynamic; using System.Globalization; using System.IO; using System.Linq; using System.Linq.Expressions; using System.Threading; using System.Threading.Tasks; namespace Newtonsoft.Json.Linq { public class JObject : JContainer, IDictionary<string, JToken>, ICollection<KeyValuePair<string, JToken>>, IEnumerable<KeyValuePair<string, JToken>>, IEnumerable, INotifyPropertyChanged, ICustomTypeDescriptor, INotifyPropertyChanging { private class JObjectDynamicProxy : DynamicProxy<JObject> { public override bool TryGetMember(JObject instance, GetMemberBinder binder, out object result) { result = instance[binder.Name]; return true; } public override bool TrySetMember(JObject instance, SetMemberBinder binder, object value) { JToken value2; if ((value2 = (value as JToken)) == null) value2 = new JValue(value); instance[binder.Name] = value2; return true; } public override IEnumerable<string> GetDynamicMemberNames(JObject instance) { return from p in instance.Properties() select p.Name; } } private readonly JPropertyKeyedCollection _properties = new JPropertyKeyedCollection(); protected override IList<JToken> ChildrenTokens => _properties; public override JTokenType Type => JTokenType.Object; public override JToken this[object key] { get { ValidationUtils.ArgumentNotNull(key, "key"); string propertyName; if ((propertyName = (key as string)) == null) throw new ArgumentException("Accessed JObject values with invalid key value: {0}. Object property name expected.".FormatWith(CultureInfo.InvariantCulture, MiscellaneousUtils.ToString(key))); return this[propertyName]; } set { ValidationUtils.ArgumentNotNull(key, "key"); string propertyName; if ((propertyName = (key as string)) == null) throw new ArgumentException("Set JObject values with invalid key value: {0}. Object property name expected.".FormatWith(CultureInfo.InvariantCulture, MiscellaneousUtils.ToString(key))); this[propertyName] = value; } } public JToken this[string propertyName] { get { ValidationUtils.ArgumentNotNull(propertyName, "propertyName"); return Property(propertyName)?.Value; } set { JProperty jProperty = Property(propertyName); if (jProperty != null) jProperty.Value = value; else { OnPropertyChanging(propertyName); Add(new JProperty(propertyName, value)); OnPropertyChanged(propertyName); } } } ICollection<string> IDictionary<string, JToken>.Keys { get { return _properties.Keys; } } ICollection<JToken> IDictionary<string, JToken>.Values { get { throw new NotImplementedException(); } } bool ICollection<KeyValuePair<string, JToken>>.IsReadOnly { get { return false; } } public event PropertyChangedEventHandler PropertyChanged; public event PropertyChangingEventHandler PropertyChanging; public override Task WriteToAsync(JsonWriter writer, CancellationToken cancellationToken, params JsonConverter[] converters) { Task task = writer.WriteStartObjectAsync(cancellationToken); if (!task.IsCompletedSucessfully()) return <WriteToAsync>g__AwaitProperties|0_0(task, 0, writer, cancellationToken, converters); for (int i = 0; i < _properties.Count; i++) { task = _properties[i].WriteToAsync(writer, cancellationToken, converters); if (!task.IsCompletedSucessfully()) return <WriteToAsync>g__AwaitProperties|0_0(task, i + 1, writer, cancellationToken, converters); } return writer.WriteEndObjectAsync(cancellationToken); } public new static Task<JObject> LoadAsync(JsonReader reader, CancellationToken cancellationToken = default(CancellationToken)) { return LoadAsync(reader, null, cancellationToken); } public new static async Task<JObject> LoadAsync(JsonReader reader, JsonLoadSettings settings, CancellationToken cancellationToken = default(CancellationToken)) { ValidationUtils.ArgumentNotNull(reader, "reader"); if (reader.TokenType == JsonToken.None && !(await reader.ReadAsync(cancellationToken).ConfigureAwait(false))) throw JsonReaderException.Create(reader, "Error reading JObject from JsonReader."); await reader.MoveToContentAsync(cancellationToken).ConfigureAwait(false); if (reader.TokenType != JsonToken.StartObject) throw JsonReaderException.Create(reader, "Error reading JObject from JsonReader. Current JsonReader item is not an object: {0}".FormatWith(CultureInfo.InvariantCulture, reader.TokenType)); JObject o = new JObject(); o.SetLineInfo(reader as IJsonLineInfo, settings); await o.ReadTokenFromAsync(reader, settings, cancellationToken).ConfigureAwait(false); return o; } public JObject() { } public JObject(JObject other) : base(other) { } public JObject(params object[] content) : this((object)content) { } public JObject(object content) { Add(content); } internal override bool DeepEquals(JToken node) { JObject jObject; if ((jObject = (node as JObject)) == null) return false; return _properties.Compare(jObject._properties); } internal override int IndexOfItem(JToken item) { return _properties.IndexOfReference(item); } internal override void InsertItem(int index, JToken item, bool skipParentCheck) { if (item == null || item.Type != JTokenType.Comment) base.InsertItem(index, item, skipParentCheck); } internal override void ValidateToken(JToken o, JToken existing) { ValidationUtils.ArgumentNotNull(o, "o"); if (o.Type != JTokenType.Property) throw new ArgumentException("Can not add {0} to {1}.".FormatWith(CultureInfo.InvariantCulture, o.GetType(), GetType())); JProperty jProperty = (JProperty)o; if (existing != null) { JProperty jProperty2 = (JProperty)existing; if (jProperty.Name == jProperty2.Name) return; } if (_properties.TryGetValue(jProperty.Name, out existing)) throw new ArgumentException("Can not add property {0} to {1}. Property with the same name already exists on object.".FormatWith(CultureInfo.InvariantCulture, jProperty.Name, GetType())); } internal override void MergeItem(object content, JsonMergeSettings settings) { JObject jObject; if ((jObject = (content as JObject)) != null) { foreach (KeyValuePair<string, JToken> item in jObject) { JProperty jProperty = Property(item.Key); if (jProperty == null) Add(item.Key, item.Value); else if (item.Value != null) { JContainer jContainer; if ((jContainer = (jProperty.Value as JContainer)) == null || jContainer.Type != item.Value.Type) { if (!IsNull(item.Value) || (settings != null && settings.MergeNullValueHandling == MergeNullValueHandling.Merge)) jProperty.Value = item.Value; } else jContainer.Merge(item.Value, settings); } } } } private static bool IsNull(JToken token) { if (token.Type == JTokenType.Null) return true; JValue jValue; if ((jValue = (token as JValue)) != null && jValue.Value == null) return true; return false; } internal void InternalPropertyChanged(JProperty childProperty) { OnPropertyChanged(childProperty.Name); if (_listChanged != null) OnListChanged(new ListChangedEventArgs(ListChangedType.ItemChanged, IndexOfItem(childProperty))); if (_collectionChanged != null) OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Replace, childProperty, childProperty, IndexOfItem(childProperty))); } internal void InternalPropertyChanging(JProperty childProperty) { OnPropertyChanging(childProperty.Name); } internal override JToken CloneToken() { return new JObject(this); } public IEnumerable<JProperty> Properties() { return _properties.Cast<JProperty>(); } public JProperty Property(string name) { if (name == null) return null; _properties.TryGetValue(name, out JToken value); return (JProperty)value; } public JEnumerable<JToken> PropertyValues() { return new JEnumerable<JToken>(from p in Properties() select p.Value); } public new static JObject Load(JsonReader reader) { return Load(reader, null); } public new static JObject Load(JsonReader reader, JsonLoadSettings settings) { ValidationUtils.ArgumentNotNull(reader, "reader"); if (reader.TokenType == JsonToken.None && !reader.Read()) throw JsonReaderException.Create(reader, "Error reading JObject from JsonReader."); reader.MoveToContent(); if (reader.TokenType != JsonToken.StartObject) throw JsonReaderException.Create(reader, "Error reading JObject from JsonReader. Current JsonReader item is not an object: {0}".FormatWith(CultureInfo.InvariantCulture, reader.TokenType)); JObject jObject = new JObject(); jObject.SetLineInfo(reader as IJsonLineInfo, settings); jObject.ReadTokenFrom(reader, settings); return jObject; } public new static JObject Parse(string json) { return Parse(json, null); } public new static JObject Parse(string json, JsonLoadSettings settings) { using (JsonReader jsonReader = new JsonTextReader(new StringReader(json))) { JObject result = Load(jsonReader, settings); while (jsonReader.Read()) { } return result; } } public new static JObject FromObject(object o) { return FromObject(o, JsonSerializer.CreateDefault()); } public new static JObject FromObject(object o, JsonSerializer jsonSerializer) { JToken jToken = JToken.FromObjectInternal(o, jsonSerializer); if (jToken != null && jToken.Type != JTokenType.Object) throw new ArgumentException("Object serialized to {0}. JObject instance expected.".FormatWith(CultureInfo.InvariantCulture, jToken.Type)); return (JObject)jToken; } public override void WriteTo(JsonWriter writer, params JsonConverter[] converters) { writer.WriteStartObject(); for (int i = 0; i < _properties.Count; i++) { _properties[i].WriteTo(writer, converters); } writer.WriteEndObject(); } public JToken GetValue(string propertyName) { return GetValue(propertyName, StringComparison.Ordinal); } public JToken GetValue(string propertyName, StringComparison comparison) { if (propertyName == null) return null; JProperty jProperty = Property(propertyName); if (jProperty != null) return jProperty.Value; if (comparison != StringComparison.Ordinal) { foreach (JProperty property in _properties) { if (string.Equals(property.Name, propertyName, comparison)) return property.Value; } } return null; } public bool TryGetValue(string propertyName, StringComparison comparison, out JToken value) { value = GetValue(propertyName, comparison); return value != null; } public void Add(string propertyName, JToken value) { Add(new JProperty(propertyName, value)); } public bool ContainsKey(string propertyName) { ValidationUtils.ArgumentNotNull(propertyName, "propertyName"); return _properties.Contains(propertyName); } public bool Remove(string propertyName) { JProperty jProperty = Property(propertyName); if (jProperty == null) return false; jProperty.Remove(); return true; } public bool TryGetValue(string propertyName, out JToken value) { JProperty jProperty = Property(propertyName); if (jProperty == null) { value = null; return false; } value = jProperty.Value; return true; } void ICollection<KeyValuePair<string, JToken>>.Add(KeyValuePair<string, JToken> item) { Add(new JProperty(item.Key, item.Value)); } void ICollection<KeyValuePair<string, JToken>>.Clear() { RemoveAll(); } bool ICollection<KeyValuePair<string, JToken>>.Contains(KeyValuePair<string, JToken> item) { JProperty jProperty = Property(item.Key); if (jProperty == null) return false; return jProperty.Value == item.Value; } void ICollection<KeyValuePair<string, JToken>>.CopyTo(KeyValuePair<string, JToken>[] array, int arrayIndex) { if (array == null) throw new ArgumentNullException("array"); if (arrayIndex < 0) throw new ArgumentOutOfRangeException("arrayIndex", "arrayIndex is less than 0."); if (arrayIndex >= array.Length && arrayIndex != 0) throw new ArgumentException("arrayIndex is equal to or greater than the length of array."); if (base.Count > array.Length - arrayIndex) throw new ArgumentException("The number of elements in the source JObject is greater than the available space from arrayIndex to the end of the destination array."); int num = 0; foreach (JProperty property in _properties) { array[arrayIndex + num] = new KeyValuePair<string, JToken>(property.Name, property.Value); num++; } } bool ICollection<KeyValuePair<string, JToken>>.Remove(KeyValuePair<string, JToken> item) { if (!((ICollection<KeyValuePair<string, JToken>>)this).Contains(item)) return false; ((IDictionary<string, JToken>)this).Remove(item.Key); return true; } internal override int GetDeepHashCode() { return ContentsHashCode(); } public IEnumerator<KeyValuePair<string, JToken>> GetEnumerator() { foreach (JProperty property in _properties) { yield return new KeyValuePair<string, JToken>(property.Name, property.Value); } } protected virtual void OnPropertyChanged(string propertyName) { this.PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); } protected virtual void OnPropertyChanging(string propertyName) { this.PropertyChanging?.Invoke(this, new PropertyChangingEventArgs(propertyName)); } PropertyDescriptorCollection ICustomTypeDescriptor.GetProperties() { return ((ICustomTypeDescriptor)this).GetProperties((Attribute[])null); } PropertyDescriptorCollection ICustomTypeDescriptor.GetProperties(Attribute[] attributes) { PropertyDescriptorCollection propertyDescriptorCollection = new PropertyDescriptorCollection(null); using (IEnumerator<KeyValuePair<string, JToken>> enumerator = GetEnumerator()) { while (enumerator.MoveNext()) { propertyDescriptorCollection.Add(new JPropertyDescriptor(enumerator.Current.Key)); } return propertyDescriptorCollection; } } AttributeCollection ICustomTypeDescriptor.GetAttributes() { return AttributeCollection.Empty; } string ICustomTypeDescriptor.GetClassName() { return null; } string ICustomTypeDescriptor.GetComponentName() { return null; } TypeConverter ICustomTypeDescriptor.GetConverter() { return new TypeConverter(); } EventDescriptor ICustomTypeDescriptor.GetDefaultEvent() { return null; } PropertyDescriptor ICustomTypeDescriptor.GetDefaultProperty() { return null; } object ICustomTypeDescriptor.GetEditor(Type editorBaseType) { return null; } EventDescriptorCollection ICustomTypeDescriptor.GetEvents(Attribute[] attributes) { return EventDescriptorCollection.Empty; } EventDescriptorCollection ICustomTypeDescriptor.GetEvents() { return EventDescriptorCollection.Empty; } object ICustomTypeDescriptor.GetPropertyOwner(PropertyDescriptor pd) { if (pd is JPropertyDescriptor) return this; return null; } protected override DynamicMetaObject GetMetaObject(Expression parameter) { return new DynamicProxyMetaObject<JObject>(parameter, this, new JObjectDynamicProxy()); } } }