浏览代码

readd nullable number converters

crobibero 4 年之前
父节点
当前提交
9b2359a453

+ 56 - 0
MediaBrowser.Common/Json/Converters/JsonNullableInt32Converter.cs

@@ -0,0 +1,56 @@
+using System;
+using System.Buffers;
+using System.Buffers.Text;
+using System.Text.Json;
+using System.Text.Json.Serialization;
+
+namespace MediaBrowser.Common.Json.Converters
+{
+    /// <summary>
+    /// Converts a nullable int32 object or value to/from JSON.
+    /// Required - some clients send an empty string.
+    /// </summary>
+    public class JsonNullableInt32Converter : JsonConverter<int?>
+    {
+        /// <inheritdoc />
+        public override int? Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
+        {
+            if (reader.TokenType == JsonTokenType.String)
+            {
+                ReadOnlySpan<byte> span = reader.HasValueSequence ? reader.ValueSequence.ToArray() : reader.ValueSpan;
+                if (Utf8Parser.TryParse(span, out int number, out int bytesConsumed) && span.Length == bytesConsumed)
+                {
+                    return number;
+                }
+
+                var stringValue = reader.GetString().AsSpan();
+
+                // value is null or empty, just return null.
+                if (stringValue.IsEmpty)
+                {
+                    return null;
+                }
+
+                if (int.TryParse(stringValue, out number))
+                {
+                    return number;
+                }
+            }
+
+            return reader.GetInt32();
+        }
+
+        /// <inheritdoc />
+        public override void Write(Utf8JsonWriter writer, int? value, JsonSerializerOptions options)
+        {
+            if (value is null)
+            {
+                writer.WriteNullValue();
+            }
+            else
+            {
+                writer.WriteNumberValue(value.Value);
+            }
+        }
+    }
+}

+ 71 - 0
MediaBrowser.Common/Json/Converters/JsonNullableInt64Converter.cs

@@ -0,0 +1,71 @@
+using System;
+using System.Buffers;
+using System.Buffers.Text;
+using System.Text.Json;
+using System.Text.Json.Serialization;
+
+namespace MediaBrowser.Common.Json.Converters
+{
+    /// <summary>
+    /// Parse JSON string as nullable long.
+    /// Javascript does not support 64-bit integers.
+    /// Required - some clients send an empty string.
+    /// </summary>
+    public class JsonNullableInt64Converter : JsonConverter<long?>
+    {
+        /// <summary>
+        /// Read JSON string as int64.
+        /// </summary>
+        /// <param name="reader"><see cref="Utf8JsonReader"/>.</param>
+        /// <param name="type">Type.</param>
+        /// <param name="options">Options.</param>
+        /// <returns>Parsed value.</returns>
+        public override long? Read(ref Utf8JsonReader reader, Type type, JsonSerializerOptions options)
+        {
+            if (reader.TokenType == JsonTokenType.String)
+            {
+                // try to parse number directly from bytes
+                var span = reader.HasValueSequence ? reader.ValueSequence.ToArray() : reader.ValueSpan;
+                if (Utf8Parser.TryParse(span, out long number, out var bytesConsumed) && span.Length == bytesConsumed)
+                {
+                    return number;
+                }
+
+                var stringValue = reader.GetString().AsSpan();
+
+                // value is null or empty, just return null.
+                if (stringValue.IsEmpty)
+                {
+                    return null;
+                }
+
+                // try to parse from a string if the above failed, this covers cases with other escaped/UTF characters
+                if (long.TryParse(stringValue, out number))
+                {
+                    return number;
+                }
+            }
+
+            // fallback to default handling
+            return reader.GetInt64();
+        }
+
+        /// <summary>
+        /// Write long to JSON long.
+        /// </summary>
+        /// <param name="writer"><see cref="Utf8JsonWriter"/>.</param>
+        /// <param name="value">Value to write.</param>
+        /// <param name="options">Options.</param>
+        public override void Write(Utf8JsonWriter writer, long? value, JsonSerializerOptions options)
+        {
+            if (value is null)
+            {
+                writer.WriteNullValue();
+            }
+            else
+            {
+                writer.WriteNumberValue(value.Value);
+            }
+        }
+    }
+}

+ 2 - 0
MediaBrowser.Common/Json/JsonDefaults.cs

@@ -31,6 +31,8 @@ namespace MediaBrowser.Common.Json
 
             options.Converters.Add(new JsonGuidConverter());
             options.Converters.Add(new JsonStringEnumConverter());
+            options.Converters.Add(new JsonNullableInt32Converter());
+            options.Converters.Add(new JsonNullableInt64Converter());
 
             return options;
         }