Add string-based WriteAsProperty overload to JsonElement. (dotnet/corefx#37789)
authorAhson Khan <ahkha@microsoft.com>
Mon, 20 May 2019 09:57:17 +0000 (02:57 -0700)
committerGitHub <noreply@github.com>
Mon, 20 May 2019 09:57:17 +0000 (02:57 -0700)
* Add string-based WriteAsProperty overload to JsonElement.

* Address PR feedback - remove UTF-16 from the comments.

Commit migrated from https://github.com/dotnet/corefx/commit/189766719a059512a515d488efc5c65c7abf0650

src/libraries/System.Text.Json/ref/System.Text.Json.cs
src/libraries/System.Text.Json/src/System/Text/Json/Document/JsonElement.cs
src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonSerializer.Write.HandleDictionary.cs
src/libraries/System.Text.Json/tests/JsonElementWriteTests.cs

index 47fbbcb..82fd50a 100644 (file)
@@ -73,6 +73,7 @@ namespace System.Text.Json
         public bool TryGetUInt64(out ulong value) { throw null; }
         public void WriteAsProperty(System.ReadOnlySpan<byte> utf8PropertyName, System.Text.Json.Utf8JsonWriter writer) { }
         public void WriteAsProperty(System.ReadOnlySpan<char> propertyName, System.Text.Json.Utf8JsonWriter writer) { }
+        public void WriteAsProperty(string propertyName, System.Text.Json.Utf8JsonWriter writer) { }
         public void WriteAsValue(System.Text.Json.Utf8JsonWriter writer) { }
         public partial struct ArrayEnumerator : System.Collections.Generic.IEnumerable<System.Text.Json.JsonElement>, System.Collections.Generic.IEnumerator<System.Text.Json.JsonElement>, System.Collections.IEnumerable, System.Collections.IEnumerator, System.IDisposable
         {
index 1ff367a..6dbebf8 100644 (file)
@@ -940,6 +940,20 @@ namespace System.Text.Json
         /// <exception cref="ObjectDisposedException">
         ///   The parent <see cref="JsonDocument"/> has been disposed.
         /// </exception>
+        public void WriteAsProperty(string propertyName, Utf8JsonWriter writer)
+            => WriteAsProperty(propertyName.AsSpan(), writer);
+
+        /// <summary>
+        ///   Write the element into the provided writer as a named object property.
+        /// </summary>
+        /// <param name="propertyName">The name for this value within the JSON object.</param>
+        /// <param name="writer">The writer.</param>
+        /// <exception cref="InvalidOperationException">
+        ///   This value's <see cref="Type"/> is <see cref="JsonValueType.Undefined"/>.
+        /// </exception>
+        /// <exception cref="ObjectDisposedException">
+        ///   The parent <see cref="JsonDocument"/> has been disposed.
+        /// </exception>
         public void WriteAsProperty(ReadOnlySpan<char> propertyName, Utf8JsonWriter writer)
         {
             CheckValidInstance();
index 3ffe079..b689a53 100644 (file)
@@ -166,7 +166,7 @@ namespace System.Text.Json.Serialization
                 Debug.Assert(entry.Key is string);
 
                 string propertyName = (string)entry.Key;
-                element.WriteAsProperty(propertyName.AsSpan(), writer);
+                element.WriteAsProperty(propertyName, writer);
             }
             else
             {
index 70e2008..f7b88d6 100644 (file)
@@ -377,6 +377,21 @@ null,
         [Theory]
         [InlineData(false)]
         [InlineData(true)]
+        public static void WriteNullStringAsProperty(bool indented)
+        {
+            WritePropertyValueBothForms(
+                indented,
+                null,
+                "\"\"",
+                @"{
+  """": """"
+}",
+                "{\"\":\"\"}");
+        }
+
+        [Theory]
+        [InlineData(false)]
+        [InlineData(true)]
         public static void WriteNumberAsProperty(bool indented)
         {
             WritePropertyValueBothForms(
@@ -864,6 +879,7 @@ null,
                 {
                     foreach (JsonElement val in root.EnumerateArray())
                     {
+                        val.WriteAsProperty(CharLabel, writer);
                         val.WriteAsProperty(CharLabel.AsSpan(), writer);
                         val.WriteAsProperty(byteUtf8, writer);
                     }
@@ -871,13 +887,13 @@ null,
                     writer.Flush();
 
                     AssertContents(
-                        "\"char\":null,\"byte\":null," +
-                            "\"char\":false,\"byte\":false," +
-                            "\"char\":true,\"byte\":true," +
-                            "\"char\":\"hi\",\"byte\":\"hi\"," +
-                            "\"char\":5,\"byte\":5," +
-                            "\"char\":{},\"byte\":{}," +
-                            "\"char\":[],\"byte\":[]",
+                        "\"char\":null,\"char\":null,\"byte\":null," +
+                            "\"char\":false,\"char\":false,\"byte\":false," +
+                            "\"char\":true,\"char\":true,\"byte\":true," +
+                            "\"char\":\"hi\",\"char\":\"hi\",\"byte\":\"hi\"," +
+                            "\"char\":5,\"char\":5,\"byte\":5," +
+                            "\"char\":{},\"char\":{},\"byte\":{}," +
+                            "\"char\":[],\"char\":[],\"byte\":[]",
                         buffer);
                 }
                 else
@@ -886,6 +902,10 @@ null,
                     {
                         JsonTestHelper.AssertThrows<InvalidOperationException>(
                             ref writer,
+                            (ref Utf8JsonWriter w) => val.WriteAsProperty(CharLabel, w));
+
+                        JsonTestHelper.AssertThrows<InvalidOperationException>(
+                            ref writer,
                             (ref Utf8JsonWriter w) => val.WriteAsProperty(CharLabel.AsSpan(), w));
 
                         JsonTestHelper.AssertThrows<InvalidOperationException>(
@@ -1010,6 +1030,13 @@ null,
         {
             WritePropertyValue(
                 indented,
+                propertyName,
+                jsonIn,
+                expectedIndent,
+                expectedMinimal);
+
+            WritePropertyValue(
+                indented,
                 propertyName.AsSpan(),
                 jsonIn,
                 expectedIndent,
@@ -1017,7 +1044,7 @@ null,
 
             WritePropertyValue(
                 indented,
-                Encoding.UTF8.GetBytes(propertyName),
+                Encoding.UTF8.GetBytes(propertyName ?? ""),
                 jsonIn,
                 expectedIndent,
                 expectedMinimal);
@@ -1025,6 +1052,42 @@ null,
 
         private static void WritePropertyValue(
             bool indented,
+            string propertyName,
+            string jsonIn,
+            string expectedIndent,
+            string expectedMinimal)
+        {
+            var buffer = new ArrayBufferWriter<byte>(1024);
+            string temp = $" [  {jsonIn}  ]";
+            using (JsonDocument doc = JsonDocument.Parse(temp, s_readerOptions))
+            {
+                JsonElement target = doc.RootElement[0];
+
+                var options = new JsonWriterOptions
+                {
+                    Indented = indented,
+                };
+
+                var writer = new Utf8JsonWriter(buffer, options);
+
+                writer.WriteStartObject();
+                target.WriteAsProperty(propertyName, writer);
+                writer.WriteEndObject();
+                writer.Flush();
+
+                if (indented && s_replaceNewlines)
+                {
+                    AssertContents(
+                        expectedIndent.Replace(CompiledNewline, Environment.NewLine),
+                        buffer);
+                }
+
+                AssertContents(indented ? expectedIndent : expectedMinimal, buffer);
+            }
+        }
+
+        private static void WritePropertyValue(
+            bool indented,
             ReadOnlySpan<char> propertyName,
             string jsonIn,
             string expectedIndent,