예제 #1
0
        private byte[] GetByteArray(object value)
        {
#if HAVE_LINQ
            if (value.GetType().FullName == BinaryTypeName)
            {
                EnsureReflectionObject(value.GetType());
                MiscellaneousUtils.Assert(_reflectionObject != null);

                return((byte[])_reflectionObject.GetValue(value, BinaryToArrayName) !);
            }
#endif
#if HAVE_ADO_NET
            if (value is SqlBinary binary)
            {
                return(binary.Value);
            }
#endif

            throw new JsonSerializationException(
                      "Unexpected value type when writing binary: {0}".FormatWith(
                          CultureInfo.InvariantCulture,
                          value.GetType()
                          )
                      );
        }
예제 #2
0
        /// <summary>
        /// Reads the JSON representation of the object.
        /// </summary>
        /// <param name="reader">The <see cref="JsonReader"/> to read from.</param>
        /// <param name="objectType">Type of the object.</param>
        /// <param name="existingValue">The existing value of object being read.</param>
        /// <param name="serializer">The calling serializer.</param>
        /// <returns>The object value.</returns>
        public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
        {
            EnsureReflectionObject(objectType);
            MiscellaneousUtils.Assert(_reflectionObject != null);

            object entityKeyMember = _reflectionObject.Creator();

            ReadAndAssertProperty(reader, KeyPropertyName);
            reader.ReadAndAssert();
            _reflectionObject.SetValue(entityKeyMember, KeyPropertyName, reader.Value?.ToString());

            ReadAndAssertProperty(reader, TypePropertyName);
            reader.ReadAndAssert();
            string type = reader.Value?.ToString();

            Type t = Type.GetType(type);

            ReadAndAssertProperty(reader, ValuePropertyName);
            reader.ReadAndAssert();
            _reflectionObject.SetValue(entityKeyMember, ValuePropertyName, serializer.Deserialize(reader, t));

            reader.ReadAndAssert();

            return(entityKeyMember);
        }
예제 #3
0
        public void AddProperty(JsonProperty property)
        {
            MiscellaneousUtils.Assert(property.PropertyName != null);

            if (Contains(property.PropertyName))
            {
                // don't overwrite existing property with ignored property
                if (property.Ignored)
                {
                    return;
                }

                var existingProperty  = this[property.PropertyName];
                var duplicateProperty = true;

                if (existingProperty.Ignored)
                {
                    // remove ignored property so it can be replaced in collection
                    Remove(existingProperty);
                    duplicateProperty = false;
                }
                else
                {
                    if (property.DeclaringType != null && existingProperty.DeclaringType != null)
                    {
                        if (property.DeclaringType.IsSubclassOf(existingProperty.DeclaringType) ||
                            existingProperty.DeclaringType.IsInterface() &&
                            property.DeclaringType.ImplementInterface(existingProperty.DeclaringType))
                        {
                            // current property is on a derived class and hides the existing
                            Remove(existingProperty);
                            duplicateProperty = false;
                        }
                        if (existingProperty.DeclaringType.IsSubclassOf(property.DeclaringType) ||
                            property.DeclaringType.IsInterface() && existingProperty.DeclaringType.ImplementInterface(property.DeclaringType))
                        {
                            // current property is hidden by the existing so don't add it
                            return;
                        }

                        if (_type.ImplementInterface(existingProperty.DeclaringType) && _type.ImplementInterface(property.DeclaringType))
                        {
                            // current property was already defined on another interface
                            return;
                        }
                    }
                }

                if (duplicateProperty)
                {
                    throw new JsonSerializationException(
                              "A member with the name '{0}' already exists on '{1}'. Use the JsonPropertyAttribute to specify another name.".FormatWith(
                                  CultureInfo.InvariantCulture, property.PropertyName, _type));
                }
            }

            Add(property);
        }
예제 #4
0
        /// <summary>
        /// Writes the JSON representation of the object.
        /// </summary>
        /// <param name="writer">The <see cref="JsonWriter"/> to write to.</param>
        /// <param name="value">The value.</param>
        /// <param name="serializer">The calling serializer.</param>
        public override void WriteJson(JsonWriter writer, object?value, JsonSerializer serializer)
        {
            if (value == null)
            {
                writer.WriteNull();
                return;
            }

            EnsureReflectionObject(value.GetType());
            MiscellaneousUtils.Assert(_reflectionObject != null);

            DefaultContractResolver?resolver =
                serializer.ContractResolver as DefaultContractResolver;

            string keyName  = (string)_reflectionObject.GetValue(value, KeyPropertyName) !;
            object?keyValue = _reflectionObject.GetValue(value, ValuePropertyName);

            Type?keyValueType = keyValue?.GetType();

            writer.WriteStartObject();
            writer.WritePropertyName(
                (resolver != null)
                  ? resolver.GetResolvedPropertyName(KeyPropertyName)
                  : KeyPropertyName
                );
            writer.WriteValue(keyName);
            writer.WritePropertyName(
                (resolver != null)
                  ? resolver.GetResolvedPropertyName(TypePropertyName)
                  : TypePropertyName
                );
            writer.WriteValue(keyValueType?.FullName);

            writer.WritePropertyName(
                (resolver != null)
                  ? resolver.GetResolvedPropertyName(ValuePropertyName)
                  : ValuePropertyName
                );

            if (keyValueType != null)
            {
                if (
                    JsonSerializerInternalWriter.TryConvertToString(
                        keyValue !,
                        keyValueType,
                        out string?valueJson
                        )
                    )
                {
                    writer.WriteValue(valueJson);
                }
                else
                {
                    writer.WriteValue(keyValue);
                }
            }
예제 #5
0
        /// <summary>
        /// Reads the JSON representation of the object.
        /// </summary>
        /// <param name="reader">The <see cref="JsonReader"/> to read from.</param>
        /// <param name="objectType">Type of the object.</param>
        /// <param name="existingValue">The existing value of object being read.</param>
        /// <param name="serializer">The calling serializer.</param>
        /// <returns>The object value.</returns>
        public override object?ReadJson(JsonReader reader, Type objectType, object?existingValue, JsonSerializer serializer)
        {
            if (reader.TokenType == JsonToken.Null)
            {
                if (!ReflectionUtils.IsNullable(objectType))
                {
                    throw JsonSerializationException.Create(reader, "Cannot convert null value to {0}.".FormatWith(CultureInfo.InvariantCulture, objectType));
                }

                return(null);
            }

            byte[] data;

            if (reader.TokenType == JsonToken.StartArray)
            {
                data = ReadByteArray(reader);
            }
            else if (reader.TokenType == JsonToken.String)
            {
                // current token is already at base64 string
                // unable to call ReadAsBytes so do it the old fashion way
                string encodedData = reader.Value !.ToString();
                data = Convert.FromBase64String(encodedData);
            }
            else
            {
                throw JsonSerializationException.Create(reader, "Unexpected token parsing binary. Expected String or StartArray, got {0}.".FormatWith(CultureInfo.InvariantCulture, reader.TokenType));
            }

            Type t = (ReflectionUtils.IsNullableType(objectType))
                ? Nullable.GetUnderlyingType(objectType)
                : objectType;

#if HAVE_LINQ
            if (t.FullName == BinaryTypeName)
            {
                EnsureReflectionObject(t);
                MiscellaneousUtils.Assert(_reflectionObject != null);

                return(_reflectionObject.Creator !(data));
            }
#endif

#if HAVE_ADO_NET
            if (t == typeof(SqlBinary))
            {
                return(new SqlBinary(data));
            }
#endif

            throw JsonSerializationException.Create(reader, "Unexpected object type when writing binary: {0}".FormatWith(CultureInfo.InvariantCulture, objectType));
        }
예제 #6
0
            public JToken this[int index]
            {
                get
                {
                    if (index != 0)
                    {
                        throw new IndexOutOfRangeException();
                    }

                    MiscellaneousUtils.Assert(_token != null);
                    return(_token);
                }
                set
                {
                    if (index != 0)
                    {
                        throw new IndexOutOfRangeException();
                    }

                    _token = value;
                }
            }
예제 #7
0
        private async Task ReadContentFromAsync(JsonReader reader, JsonLoadSettings?settings, CancellationToken cancellationToken = default)
        {
            IJsonLineInfo?lineInfo = reader as IJsonLineInfo;

            JContainer?parent = this;

            do
            {
                if (parent is JProperty p && p.Value != null)
                {
                    if (parent == this)
                    {
                        return;
                    }

                    parent = parent.Parent;
                }

                MiscellaneousUtils.Assert(parent != null);

                switch (reader.TokenType)
                {
                case JsonToken.None:
                    // new reader. move to actual content
                    break;

                case JsonToken.StartArray:
                    JArray a = new JArray();
                    a.SetLineInfo(lineInfo, settings);
                    parent.Add(a);
                    parent = a;
                    break;

                case JsonToken.EndArray:
                    if (parent == this)
                    {
                        return;
                    }

                    parent = parent.Parent;
                    break;

                case JsonToken.StartObject:
                    JObject o = new JObject();
                    o.SetLineInfo(lineInfo, settings);
                    parent.Add(o);
                    parent = o;
                    break;

                case JsonToken.EndObject:
                    if (parent == this)
                    {
                        return;
                    }

                    parent = parent.Parent;
                    break;

                case JsonToken.StartConstructor:
                    JConstructor constructor = new JConstructor(reader.Value !.ToString());
                    constructor.SetLineInfo(lineInfo, settings);
                    parent.Add(constructor);
                    parent = constructor;
                    break;

                case JsonToken.EndConstructor:
                    if (parent == this)
                    {
                        return;
                    }

                    parent = parent.Parent;
                    break;

                case JsonToken.String:
                case JsonToken.Integer:
                case JsonToken.Float:
                case JsonToken.Date:
                case JsonToken.Boolean:
                case JsonToken.Bytes:
                    JValue v = new JValue(reader.Value);
                    v.SetLineInfo(lineInfo, settings);
                    parent.Add(v);
                    break;

                case JsonToken.Comment:
                    if (settings != null && settings.CommentHandling == CommentHandling.Load)
                    {
                        v = JValue.CreateComment(reader.Value !.ToString());
                        v.SetLineInfo(lineInfo, settings);
                        parent.Add(v);
                    }
                    break;

                case JsonToken.Null:
                    v = JValue.CreateNull();
                    v.SetLineInfo(lineInfo, settings);
                    parent.Add(v);
                    break;

                case JsonToken.Undefined:
                    v = JValue.CreateUndefined();
                    v.SetLineInfo(lineInfo, settings);
                    parent.Add(v);
                    break;

                case JsonToken.PropertyName:
                    JProperty?property = ReadProperty(reader, settings, lineInfo, parent);
                    if (property != null)
                    {
                        parent = property;
                    }
                    else
                    {
                        await reader.SkipAsync().ConfigureAwait(false);
                    }
                    break;

                default:
                    throw new InvalidOperationException("The JsonReader should not be on a token of type {0}.".FormatWith(CultureInfo.InvariantCulture, reader.TokenType));
                }
            } while (await reader.ReadAsync(cancellationToken).ConfigureAwait(false));
        }
예제 #8
0
        internal static int Compare(JTokenType valueType, object? objA, object? objB)
        {
            if (objA == objB)
            {
                return 0;
            }
            if (objB == null)
            {
                return 1;
            }
            if (objA == null)
            {
                return -1;
            }

            switch (valueType)
            {
                case JTokenType.Integer:
                {
#if HAVE_BIG_INTEGER
                    if (objA is BigInteger integerA)
                    {
                        return CompareBigInteger(integerA, objB);
                    }
                    if (objB is BigInteger integerB)
                    {
                        return -CompareBigInteger(integerB, objA);
                    }
#endif
                    if (objA is ulong || objB is ulong || objA is decimal || objB is decimal)
                    {
                        return Convert
                            .ToDecimal(objA, CultureInfo.InvariantCulture)
                            .CompareTo(Convert.ToDecimal(objB, CultureInfo.InvariantCulture));
                    }
                    else if (objA is float || objB is float || objA is double || objB is double)
                    {
                        return CompareFloat(objA, objB);
                    }
                    else
                    {
                        return Convert
                            .ToInt64(objA, CultureInfo.InvariantCulture)
                            .CompareTo(Convert.ToInt64(objB, CultureInfo.InvariantCulture));
                    }
                }
                case JTokenType.Float:
                {
#if HAVE_BIG_INTEGER
                    if (objA is BigInteger integerA)
                    {
                        return CompareBigInteger(integerA, objB);
                    }
                    if (objB is BigInteger integerB)
                    {
                        return -CompareBigInteger(integerB, objA);
                    }
#endif
                    if (objA is ulong || objB is ulong || objA is decimal || objB is decimal)
                    {
                        return Convert
                            .ToDecimal(objA, CultureInfo.InvariantCulture)
                            .CompareTo(Convert.ToDecimal(objB, CultureInfo.InvariantCulture));
                    }
                    return CompareFloat(objA, objB);
                }
                case JTokenType.Comment:
                case JTokenType.String:
                case JTokenType.Raw:
                    string s1 = Convert.ToString(objA, CultureInfo.InvariantCulture);
                    string s2 = Convert.ToString(objB, CultureInfo.InvariantCulture);

                    return string.CompareOrdinal(s1, s2);
                case JTokenType.Boolean:
                    bool b1 = Convert.ToBoolean(objA, CultureInfo.InvariantCulture);
                    bool b2 = Convert.ToBoolean(objB, CultureInfo.InvariantCulture);

                    return b1.CompareTo(b2);
                case JTokenType.Date:
#if HAVE_DATE_TIME_OFFSET
                    if (objA is DateTime dateA)
                    {
#else
                    DateTime dateA = (DateTime)objA;
#endif
                    DateTime dateB;

#if HAVE_DATE_TIME_OFFSET
                        if (objB is DateTimeOffset offsetB)
                        {
                            dateB = offsetB.DateTime;
                        }
                        else
#endif
                    {
                        dateB = Convert.ToDateTime(objB, CultureInfo.InvariantCulture);
                    }

                    return dateA.CompareTo(dateB);
#if HAVE_DATE_TIME_OFFSET
                    }
                    else
                    {
                        DateTimeOffset offsetA = (DateTimeOffset)objA;
                        if (!(objB is DateTimeOffset offsetB))
                        {
                            offsetB = new DateTimeOffset(
                                Convert.ToDateTime(objB, CultureInfo.InvariantCulture)
                            );
                        }

                        return offsetA.CompareTo(offsetB);
                    }
#endif
                case JTokenType.Bytes:
                    if (!(objB is byte[] bytesB))
                    {
                        throw new ArgumentException("Object must be of type byte[].");
                    }

                    byte[]? bytesA = objA as byte[];
                    MiscellaneousUtils.Assert(bytesA != null);

                    return MiscellaneousUtils.ByteArrayCompare(bytesA!, bytesB);
                case JTokenType.Guid:
                    if (!(objB is Guid))
                    {
                        throw new ArgumentException("Object must be of type Guid.");
                    }

                    Guid guid1 = (Guid)objA;
                    Guid guid2 = (Guid)objB;

                    return guid1.CompareTo(guid2);
                case JTokenType.Uri:
                    Uri? uri2 = objB as Uri;
                    if (uri2 == null)
                    {
                        throw new ArgumentException("Object must be of type Uri.");
                    }

                    Uri uri1 = (Uri)objA;

                    return Comparer<string>.Default.Compare(uri1.ToString(), uri2.ToString());
                case JTokenType.TimeSpan:
                    if (!(objB is TimeSpan))
                    {
                        throw new ArgumentException("Object must be of type TimeSpan.");
                    }

                    TimeSpan ts1 = (TimeSpan)objA;
                    TimeSpan ts2 = (TimeSpan)objB;

                    return ts1.CompareTo(ts2);
                default:
                    throw MiscellaneousUtils.CreateArgumentOutOfRangeException(
                        nameof(valueType),
                        valueType,
                        "Unexpected value type: {0}".FormatWith(
                            CultureInfo.InvariantCulture,
                            valueType
                        )
                    );
            }
        }