Browse Source

Using DictionaryKeyPolicy during ProblemDetails.Errors conversion to JSON (#38853)

* Adding Write operation unit tests

* Updating converter to use DictionaryKeyPolicy

* Remove empty lines

* Using cleanup

* Moving to S.T.J  Serialize method
Bruno Oliveira 4 years ago
parent
commit
a39afae2bf

+ 59 - 2
src/Mvc/Mvc.Core/test/Infrastructure/ValidationProblemDetailsJsonConverterTest.cs

@@ -1,10 +1,8 @@
 // Licensed to the .NET Foundation under one or more agreements.
 // The .NET Foundation licenses this file to you under the MIT license.
 
-using System.Linq;
 using System.Text;
 using System.Text.Json;
-using Xunit;
 
 namespace Microsoft.AspNetCore.Mvc.Infrastructure;
 
@@ -135,4 +133,63 @@ public class ValidationProblemDetailsJsonConverterTest
                 Assert.Equal(new[] { "error1", "error2" }, kvp.Value);
             });
     }
+
+    [Fact]
+    public void WriteWorks()
+    {
+        var problemDetails = new ValidationProblemDetails(new Dictionary<string, string[]>() { { "Property",  new string[]{ "error0" } }})
+        {
+            Title  = "One or more validation errors occurred.",
+            Status = 400
+        };
+
+        var converter = new ValidationProblemDetailsJsonConverter();
+        using MemoryStream stream = new();
+        using Utf8JsonWriter writer = new(stream);
+
+        // Act
+        converter.Write(writer, problemDetails, null);
+
+        writer.Flush();
+        var json = Encoding.UTF8.GetString(stream.ToArray());
+
+        var expectedJSON = $"{{\"title\":\"{problemDetails.Title}\",\"status\":{problemDetails.Status}," +
+            "\"errors\":{\"Property\":[\"error0\"]}}";
+        Assert.NotNull(json);
+        Assert.Equal(expectedJSON, json);
+    }
+
+    [Fact]
+    public void WriteUsingJsonSerializerOptionsWorks()
+    {
+        var errors = new Dictionary<string, string[]>()
+        {
+            { "Property",  new string[]{ "error0" } },
+            { "TwoWords",  new string[]{ "error1" } },
+            { "TopLevelProperty.PropertyName",  new string[]{ "error2" } },
+        };
+        var problemDetails = new ValidationProblemDetails(errors)
+        {
+            Title  = "One or more validation errors occurred.",
+            Status = 400
+        };
+
+        // Act
+        var converter = new ValidationProblemDetailsJsonConverter();
+        using MemoryStream stream = new();
+        using Utf8JsonWriter writer = new(stream);
+
+        var options = new JsonOptions().JsonSerializerOptions;
+        options.DictionaryKeyPolicy = JsonNamingPolicy.CamelCase;
+
+        converter.Write(writer, problemDetails, options);
+
+        writer.Flush();
+        var json = Encoding.UTF8.GetString(stream.ToArray());
+
+        var expectedJSON = $"{{\"title\":\"{problemDetails.Title}\",\"status\":{problemDetails.Status}," +
+            "\"errors\":{\"property\":[\"error0\"],\"twoWords\":[\"error1\"],\"topLevelProperty.PropertyName\":[\"error2\"]}}";
+        Assert.NotNull(json);
+        Assert.Equal(expectedJSON, json);
+    }
 }

+ 2 - 7
src/Shared/HttpValidationProblemDetailsJsonConverter.cs

@@ -60,13 +60,8 @@ internal sealed class HttpValidationProblemDetailsJsonConverter : JsonConverter<
         writer.WriteStartObject();
         ProblemDetailsJsonConverter.WriteProblemDetails(writer, value, options);
 
-        writer.WriteStartObject(Errors);
-        foreach (var kvp in value.Errors)
-        {
-            writer.WritePropertyName(kvp.Key);
-            JsonSerializer.Serialize(writer, kvp.Value, kvp.Value?.GetType() ?? typeof(object), options);
-        }
-        writer.WriteEndObject();
+        writer.WritePropertyName(Errors);
+        JsonSerializer.Serialize(writer, value.Errors, options);
 
         writer.WriteEndObject();
     }