Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/dotnet/aspnetcore.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authormboggs1 <102692996+mboggs1@users.noreply.github.com>2022-04-19 03:32:17 +0300
committerGitHub <noreply@github.com>2022-04-19 03:32:17 +0300
commit0ab246d2ee8add862262f24e990154284a8a4631 (patch)
treeee55d4da23fa441adf936f95209ee77989c5f445
parent64ccf823287a1de02385d29497127ad5197a389d (diff)
Flow IContractResolver through JsonPatch method calls (#40966)
-rw-r--r--src/Features/JsonPatch/src/Internal/DictionaryAdapterOfTU.cs13
-rw-r--r--src/Features/JsonPatch/src/Internal/DynamicObjectAdapter.cs11
-rw-r--r--src/Features/JsonPatch/src/Internal/PocoAdapter.cs13
-rw-r--r--src/Features/JsonPatch/src/PublicAPI.Unshipped.txt3
-rw-r--r--src/Features/JsonPatch/test/Internal/DictionaryAdapterTest.cs26
-rw-r--r--src/Features/JsonPatch/test/Internal/DynamicObjectAdapterTest.cs23
-rw-r--r--src/Features/JsonPatch/test/Internal/PocoAdapterTest.cs31
-rw-r--r--src/Features/JsonPatch/test/TestObjectModels/HeterogenousCollection.cs44
8 files changed, 151 insertions, 13 deletions
diff --git a/src/Features/JsonPatch/src/Internal/DictionaryAdapterOfTU.cs b/src/Features/JsonPatch/src/Internal/DictionaryAdapterOfTU.cs
index 0b7cad675a..6dc39a5376 100644
--- a/src/Features/JsonPatch/src/Internal/DictionaryAdapterOfTU.cs
+++ b/src/Features/JsonPatch/src/Internal/DictionaryAdapterOfTU.cs
@@ -31,7 +31,7 @@ public class DictionaryAdapter<TKey, TValue> : IAdapter
return false;
}
- if (!TryConvertValue(value, out var convertedValue, out errorMessage))
+ if (!TryConvertValue(value, contractResolver, out var convertedValue, out errorMessage))
{
return false;
}
@@ -119,7 +119,7 @@ public class DictionaryAdapter<TKey, TValue> : IAdapter
return false;
}
- if (!TryConvertValue(value, out var convertedValue, out errorMessage))
+ if (!TryConvertValue(value, contractResolver, out var convertedValue, out errorMessage))
{
return false;
}
@@ -153,7 +153,7 @@ public class DictionaryAdapter<TKey, TValue> : IAdapter
return false;
}
- if (!TryConvertValue(value, out var convertedValue, out errorMessage))
+ if (!TryConvertValue(value, contractResolver, out var convertedValue, out errorMessage))
{
return false;
}
@@ -229,7 +229,12 @@ public class DictionaryAdapter<TKey, TValue> : IAdapter
protected virtual bool TryConvertValue(object value, out TValue convertedValue, out string errorMessage)
{
- var conversionResult = ConversionResultProvider.ConvertTo(value, typeof(TValue));
+ return TryConvertValue(value, null, out convertedValue, out errorMessage);
+ }
+
+ protected virtual bool TryConvertValue(object value, IContractResolver contractResolver, out TValue convertedValue, out string errorMessage)
+ {
+ var conversionResult = ConversionResultProvider.ConvertTo(value, typeof(TValue), contractResolver);
if (conversionResult.CanBeConverted)
{
errorMessage = null;
diff --git a/src/Features/JsonPatch/src/Internal/DynamicObjectAdapter.cs b/src/Features/JsonPatch/src/Internal/DynamicObjectAdapter.cs
index 626030e260..64168364d9 100644
--- a/src/Features/JsonPatch/src/Internal/DynamicObjectAdapter.cs
+++ b/src/Features/JsonPatch/src/Internal/DynamicObjectAdapter.cs
@@ -92,7 +92,7 @@ public class DynamicObjectAdapter : IAdapter
return false;
}
- if (!TryConvertValue(value, property.GetType(), out var convertedValue))
+ if (!TryConvertValue(value, property.GetType(), contractResolver, out var convertedValue))
{
errorMessage = Resources.FormatInvalidValueForProperty(value);
return false;
@@ -124,7 +124,7 @@ public class DynamicObjectAdapter : IAdapter
return false;
}
- if (!TryConvertValue(value, property.GetType(), out var convertedValue))
+ if (!TryConvertValue(value, property.GetType(), contractResolver, out var convertedValue))
{
errorMessage = Resources.FormatInvalidValueForProperty(value);
return false;
@@ -236,7 +236,12 @@ public class DynamicObjectAdapter : IAdapter
protected virtual bool TryConvertValue(object value, Type propertyType, out object convertedValue)
{
- var conversionResult = ConversionResultProvider.ConvertTo(value, propertyType);
+ return TryConvertValue(value, propertyType, null, out convertedValue);
+ }
+
+ protected virtual bool TryConvertValue(object value, Type propertyType, IContractResolver contractResolver, out object convertedValue)
+ {
+ var conversionResult = ConversionResultProvider.ConvertTo(value, propertyType, contractResolver);
if (!conversionResult.CanBeConverted)
{
convertedValue = null;
diff --git a/src/Features/JsonPatch/src/Internal/PocoAdapter.cs b/src/Features/JsonPatch/src/Internal/PocoAdapter.cs
index 49f8fe1869..00d613e3ae 100644
--- a/src/Features/JsonPatch/src/Internal/PocoAdapter.cs
+++ b/src/Features/JsonPatch/src/Internal/PocoAdapter.cs
@@ -34,7 +34,7 @@ public class PocoAdapter : IAdapter
return false;
}
- if (!TryConvertValue(value, jsonProperty.PropertyType, out var convertedValue))
+ if (!TryConvertValue(value, jsonProperty.PropertyType, contractResolver, out var convertedValue))
{
errorMessage = Resources.FormatInvalidValueForProperty(value);
return false;
@@ -125,7 +125,7 @@ public class PocoAdapter : IAdapter
return false;
}
- if (!TryConvertValue(value, jsonProperty.PropertyType, out var convertedValue))
+ if (!TryConvertValue(value, jsonProperty.PropertyType, contractResolver, out var convertedValue))
{
errorMessage = Resources.FormatInvalidValueForProperty(value);
return false;
@@ -157,7 +157,7 @@ public class PocoAdapter : IAdapter
return false;
}
- if (!TryConvertValue(value, jsonProperty.PropertyType, out var convertedValue))
+ if (!TryConvertValue(value, jsonProperty.PropertyType, contractResolver, out var convertedValue))
{
errorMessage = Resources.FormatInvalidValueForProperty(value);
return false;
@@ -225,7 +225,12 @@ public class PocoAdapter : IAdapter
protected virtual bool TryConvertValue(object value, Type propertyType, out object convertedValue)
{
- var conversionResult = ConversionResultProvider.ConvertTo(value, propertyType);
+ return TryConvertValue(value, propertyType, null, out convertedValue);
+ }
+
+ protected virtual bool TryConvertValue(object value, Type propertyType, IContractResolver contractResolver, out object convertedValue)
+ {
+ var conversionResult = ConversionResultProvider.ConvertTo(value, propertyType, contractResolver);
if (!conversionResult.CanBeConverted)
{
convertedValue = null;
diff --git a/src/Features/JsonPatch/src/PublicAPI.Unshipped.txt b/src/Features/JsonPatch/src/PublicAPI.Unshipped.txt
index 7dc5c58110..26ee55ba6f 100644
--- a/src/Features/JsonPatch/src/PublicAPI.Unshipped.txt
+++ b/src/Features/JsonPatch/src/PublicAPI.Unshipped.txt
@@ -1 +1,4 @@
#nullable enable
+~virtual Microsoft.AspNetCore.JsonPatch.Internal.DictionaryAdapter<TKey, TValue>.TryConvertValue(object value, Newtonsoft.Json.Serialization.IContractResolver contractResolver, out TValue convertedValue, out string errorMessage) -> bool
+~virtual Microsoft.AspNetCore.JsonPatch.Internal.DynamicObjectAdapter.TryConvertValue(object value, System.Type propertyType, Newtonsoft.Json.Serialization.IContractResolver contractResolver, out object convertedValue) -> bool
+~virtual Microsoft.AspNetCore.JsonPatch.Internal.PocoAdapter.TryConvertValue(object value, System.Type propertyType, Newtonsoft.Json.Serialization.IContractResolver contractResolver, out object convertedValue) -> bool
diff --git a/src/Features/JsonPatch/test/Internal/DictionaryAdapterTest.cs b/src/Features/JsonPatch/test/Internal/DictionaryAdapterTest.cs
index 5f6ee3ee9c..6d6d491952 100644
--- a/src/Features/JsonPatch/test/Internal/DictionaryAdapterTest.cs
+++ b/src/Features/JsonPatch/test/Internal/DictionaryAdapterTest.cs
@@ -4,6 +4,9 @@
using System;
using System.Collections.Generic;
using System.Globalization;
+using System.Linq;
+using Newtonsoft.Json;
+using Newtonsoft.Json.Converters;
using Newtonsoft.Json.Serialization;
using Xunit;
@@ -229,6 +232,29 @@ public class DictionaryAdapterTest
}
[Fact]
+ public void Replace_UsesCustomConverter()
+ {
+ // Arrange
+ var nameKey = "Name";
+ var dictionary = new Dictionary<string, Rectangle>(StringComparer.Ordinal);
+ dictionary.Add(nameKey, new Rectangle()
+ {
+ RectangleProperty = "Mike"
+ });
+ var dictionaryAdapter = new DictionaryAdapter<string, Rectangle>();
+ var resolver = new RectangleContractResolver();
+
+ // Act
+ var replaceStatus = dictionaryAdapter.TryReplace(dictionary, nameKey, resolver, "James", out var message);
+
+ // Assert
+ Assert.True(replaceStatus);
+ Assert.True(string.IsNullOrEmpty(message), "Expected no error message");
+ Assert.Single(dictionary);
+ Assert.Equal("James", dictionary[nameKey].RectangleProperty);
+ }
+
+ [Fact]
public void Remove_RemovesFromDictionary()
{
// Arrange
diff --git a/src/Features/JsonPatch/test/Internal/DynamicObjectAdapterTest.cs b/src/Features/JsonPatch/test/Internal/DynamicObjectAdapterTest.cs
index 021dd13100..fc3d5c0825 100644
--- a/src/Features/JsonPatch/test/Internal/DynamicObjectAdapterTest.cs
+++ b/src/Features/JsonPatch/test/Internal/DynamicObjectAdapterTest.cs
@@ -1,4 +1,4 @@
-// Licensed to the .NET Foundation under one or more agreements.
+// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
using System.Collections.Generic;
@@ -183,6 +183,27 @@ public class DynamicObjectAdapterTest
Assert.Equal($"The value 'test' is invalid for target location.", errorMessage);
}
+ [Fact]
+ public void TryReplace_UsesCustomConverter()
+ {
+ // Arrange
+ var adapter = new DynamicObjectAdapter();
+ dynamic target = new WriteOnceDynamicTestObject();
+ target.NewProperty = new Rectangle();
+ var segment = "NewProperty";
+ var resolver = new RectangleContractResolver();
+
+ // Act
+ var status = adapter.TryReplace(target, segment, resolver, "new", out string errorMessage);
+
+ // Assert
+ Assert.True(status);
+ Assert.Null(errorMessage);
+ Assert.True(target.NewProperty is Rectangle);
+ var rect = (Rectangle)target.NewProperty;
+ Assert.Equal("new", rect.RectangleProperty);
+ }
+
[Theory]
[InlineData(1, 0)]
[InlineData("new", null)]
diff --git a/src/Features/JsonPatch/test/Internal/PocoAdapterTest.cs b/src/Features/JsonPatch/test/Internal/PocoAdapterTest.cs
index 47584c6953..891a3b1e30 100644
--- a/src/Features/JsonPatch/test/Internal/PocoAdapterTest.cs
+++ b/src/Features/JsonPatch/test/Internal/PocoAdapterTest.cs
@@ -1,6 +1,13 @@
-// Licensed to the .NET Foundation under one or more agreements.
+// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using Microsoft.AspNetCore.JsonPatch.IntegrationTests;
+using Newtonsoft.Json;
+using Newtonsoft.Json.Converters;
+using Newtonsoft.Json.Linq;
using Newtonsoft.Json.Serialization;
using Xunit;
@@ -193,6 +200,28 @@ public class PocoAdapterTest
}
[Fact]
+ public void TryReplace_UsesCustomConverter()
+ {
+ // Arrange
+ var adapter = new PocoAdapter();
+ var contractResolver = new RectangleContractResolver();
+ var model = new Square()
+ {
+ Rectangle = new Rectangle()
+ {
+ RectangleProperty = "Square"
+ }
+ };
+
+ // Act
+ var replaceStatus = adapter.TryReplace(model, "Rectangle", contractResolver, "Oval", out var errorMessage);
+
+ // Assert
+ Assert.Equal("Oval", model.Rectangle.RectangleProperty);
+ Assert.True(replaceStatus);
+ }
+
+ [Fact]
public void TryTest_DoesNotThrowException_IfTestSuccessful()
{
var adapter = new PocoAdapter();
diff --git a/src/Features/JsonPatch/test/TestObjectModels/HeterogenousCollection.cs b/src/Features/JsonPatch/test/TestObjectModels/HeterogenousCollection.cs
index e9d5f4e466..d1520dd7d0 100644
--- a/src/Features/JsonPatch/test/TestObjectModels/HeterogenousCollection.cs
+++ b/src/Features/JsonPatch/test/TestObjectModels/HeterogenousCollection.cs
@@ -1,7 +1,11 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
+using System;
using System.Collections.Generic;
+using Newtonsoft.Json;
+using Newtonsoft.Json.Converters;
+using Newtonsoft.Json.Serialization;
namespace Microsoft.AspNetCore.JsonPatch;
@@ -20,7 +24,47 @@ public class Rectangle : Shape
public string RectangleProperty { get; set; }
}
+public class Square : Shape
+{
+ public Rectangle Rectangle { get; set; }
+}
+
public class Canvas
{
public IList<Shape> Items { get; set; }
}
+
+public class RectangleContractResolver : DefaultContractResolver
+{
+ protected override JsonConverter ResolveContractConverter(Type objectType)
+ {
+ if (objectType == typeof(Rectangle))
+ {
+ return new RectangleJsonConverter();
+ }
+
+ return base.ResolveContractConverter(objectType);
+ }
+}
+
+public class RectangleJsonConverter : CustomCreationConverter<Rectangle>
+{
+ public override bool CanRead => true;
+
+ public override Rectangle Create(Type objectType)
+ {
+ throw new NotImplementedException();
+ }
+
+ public override object ReadJson(
+ JsonReader reader,
+ Type objectType,
+ object existingValue,
+ JsonSerializer serializer)
+ {
+ return new Rectangle()
+ {
+ RectangleProperty = reader.Value.ToString()
+ };
+ }
+}