Skip to content
代码片段 群组 项目
未验证 提交 5df6e452 编辑于 作者: Pranav K's avatar Pranav K 提交者: GitHub
浏览文件

Support a few more complex types with DefaultTempDataSerializer (#10314)

* Support a few more complex types with DefaultTempDataSerializer

Fixes https://github.com/aspnet/AspNetCore/issues/9540
No related branches found
No related tags found
无相关合并请求
......@@ -50,8 +50,7 @@ namespace Identity.DefaultUI.WebSite
.AddRoles<IdentityRole>()
.AddEntityFrameworkStores<TContext>();
services.AddMvc()
.AddNewtonsoftJson();
services.AddMvc();
services.AddSingleton<IFileVersionProvider, FileVersionProvider>();
}
......
......@@ -235,6 +235,33 @@ namespace Microsoft.AspNetCore.Mvc.NewtonsoftJson
Assert.Equal(value.ToString(), roundTripValue);
}
[Fact]
public void RoundTripTest_ListOfDateTime()
{
// Arrange
var key = "test-key";
var dateTime = new DateTime(2007, 1, 1);
var testProvider = GetTempDataSerializer();
var value = new List<DateTime>
{
dateTime,
dateTime.AddDays(3),
};
var input = new Dictionary<string, object>
{
{ key, value }
};
// Act
var bytes = testProvider.Serialize(input);
var values = testProvider.Deserialize(bytes);
// Assert
var roundTripValue = Assert.IsType<DateTime[]>(values[key]);
Assert.Equal(value, roundTripValue);
}
private class TestItem
{
public int DummyInt { get; set; }
......
......@@ -63,6 +63,14 @@ namespace Microsoft.AspNetCore.Mvc.ViewFeatures.Infrastructure
deserializedValue = null;
break;
case JsonValueType.Array:
deserializedValue = DeserializeArray(item.Value);
break;
case JsonValueType.Object:
deserializedValue = DeserializeDictionaryEntry(item.Value);
break;
default:
throw new InvalidOperationException(Resources.FormatTempData_CannotDeserializeType(item.Value.Type));
}
......@@ -73,6 +81,53 @@ namespace Microsoft.AspNetCore.Mvc.ViewFeatures.Infrastructure
return deserialized;
}
private static object DeserializeArray(in JsonElement arrayElement)
{
if (arrayElement.GetArrayLength() == 0)
{
// We have to infer the type of the array by inspecting it's elements.
// If there's nothing to inspect, return a null value since we do not know
// what type the user code is expecting.
return null;
}
if (arrayElement[0].Type == JsonValueType.String)
{
var array = new List<string>();
foreach (var item in arrayElement.EnumerateArray())
{
array.Add(item.GetString());
}
return array.ToArray();
}
else if (arrayElement[0].Type == JsonValueType.Number)
{
var array = new List<int>();
foreach (var item in arrayElement.EnumerateArray())
{
array.Add(item.GetInt32());
}
return array.ToArray();
}
throw new InvalidOperationException(Resources.FormatTempData_CannotDeserializeType(arrayElement.Type));
}
private static object DeserializeDictionaryEntry(in JsonElement objectElement)
{
var dictionary = new Dictionary<string, string>(StringComparer.Ordinal);
foreach (var item in objectElement.EnumerateObject())
{
dictionary[item.Name] = item.Value.GetString();
}
return dictionary;
}
public override byte[] Serialize(IDictionary<string, object> values)
{
if (values == null || values.Count == 0)
......@@ -126,6 +181,33 @@ namespace Microsoft.AspNetCore.Mvc.ViewFeatures.Infrastructure
case Guid guid:
writer.WriteString(key, guid);
break;
case ICollection<int> intCollection:
writer.WriteStartArray(key);
foreach (var element in intCollection)
{
writer.WriteNumberValue(element);
}
writer.WriteEndArray();
break;
case ICollection<string> stringCollection:
writer.WriteStartArray(key);
foreach (var element in stringCollection)
{
writer.WriteStringValue(element);
}
writer.WriteEndArray();
break;
case IDictionary<string, string> dictionary:
writer.WriteStartObject(key);
foreach (var element in dictionary)
{
writer.WriteString(element.Key, element.Value);
}
writer.WriteEndObject();
break;
}
}
writer.WriteEndObject();
......@@ -150,7 +232,10 @@ namespace Microsoft.AspNetCore.Mvc.ViewFeatures.Infrastructure
type == typeof(string) ||
type == typeof(bool) ||
type == typeof(DateTime) ||
type == typeof(Guid);
type == typeof(Guid) ||
typeof(ICollection<int>).IsAssignableFrom(type) ||
typeof(ICollection<string>).IsAssignableFrom(type) ||
typeof(IDictionary<string, string>).IsAssignableFrom(type);
}
}
}
......@@ -34,5 +34,26 @@ namespace Microsoft.AspNetCore.Mvc.ViewFeatures.Infrastructure
var roundTripValue = Assert.IsType<string>(values[key]);
Assert.Equal(value.ToString("r"), roundTripValue);
}
[Fact]
public override void RoundTripTest_DictionaryOfInt()
{
// Arrange
var key = "test-key";
var testProvider = GetTempDataSerializer();
var value = new Dictionary<string, int>
{
{ "Key1", 7 },
{ "Key2", 24 },
};
var input = new Dictionary<string, object>
{
{ key, value }
};
// Act
var ex = Assert.Throws<InvalidOperationException>(() => testProvider.Serialize(input));
Assert.Equal($"The '{testProvider.GetType()}' cannot serialize an object of type '{value.GetType()}'.", ex.Message);
}
}
}
......@@ -239,6 +239,119 @@ namespace Microsoft.AspNetCore.Mvc.ViewFeatures.Infrastructure
Assert.Equal(value, roundTripValue);
}
[Fact]
public void RoundTripTest_CollectionOfInts()
{
// Arrange
var key = "test-key";
var testProvider = GetTempDataSerializer();
var value = new[] { 1, 2, 4, 3 };
var input = new Dictionary<string, object>
{
{ key, value }
};
// Act
var bytes = testProvider.Serialize(input);
var values = testProvider.Deserialize(bytes);
// Assert
var roundTripValue = Assert.IsType<int[]>(values[key]);
Assert.Equal(value, roundTripValue);
}
[Fact]
public void RoundTripTest_ArrayOfStringss()
{
// Arrange
var key = "test-key";
var testProvider = GetTempDataSerializer();
var value = new[] { "Hello", "world" };
var input = new Dictionary<string, object>
{
{ key, value }
};
// Act
var bytes = testProvider.Serialize(input);
var values = testProvider.Deserialize(bytes);
// Assert
var roundTripValue = Assert.IsType<string[]>(values[key]);
Assert.Equal(value, roundTripValue);
}
[Fact]
public void RoundTripTest_ListOfStringss()
{
// Arrange
var key = "test-key";
var testProvider = GetTempDataSerializer();
var value = new List<string> { "Hello", "world" };
var input = new Dictionary<string, object>
{
{ key, value }
};
// Act
var bytes = testProvider.Serialize(input);
var values = testProvider.Deserialize(bytes);
// Assert
var roundTripValue = Assert.IsType<string[]>(values[key]);
Assert.Equal(value, roundTripValue);
}
[Fact]
public void RoundTripTest_DictionaryOfString()
{
// Arrange
var key = "test-key";
var testProvider = GetTempDataSerializer();
var value = new Dictionary<string, string>
{
{ "Key1", "Value1" },
{ "Key2", "Value2" },
};
var input = new Dictionary<string, object>
{
{ key, value }
};
// Act
var bytes = testProvider.Serialize(input);
var values = testProvider.Deserialize(bytes);
// Assert
var roundTripValue = Assert.IsType<Dictionary<string, string>>(values[key]);
Assert.Equal(value, roundTripValue);
}
[Fact]
public virtual void RoundTripTest_DictionaryOfInt()
{
// Arrange
var key = "test-key";
var testProvider = GetTempDataSerializer();
var value = new Dictionary<string, int>
{
{ "Key1", 7 },
{ "Key2", 24 },
};
var input = new Dictionary<string, object>
{
{ key, value }
};
// Act
var bytes = testProvider.Serialize(input);
var values = testProvider.Deserialize(bytes);
// Assert
var roundTripValue = Assert.IsType<Dictionary<string, int>>(values[key]);
Assert.Equal(value, roundTripValue);
}
protected abstract TempDataSerializer GetTempDataSerializer();
}
}
......
{
"solution": {
"path": "Mvc.sln",
"projects": [
"test\\WebSites\\BasicWebSite\\BasicWebSite.csproj",
"test\\WebSites\\RoutingWebSite\\Mvc.RoutingWebSite.csproj",
"test\\WebSites\\RazorWebSite\\RazorWebSite.csproj",
"test\\WebSites\\FormatterWebSite\\FormatterWebSite.csproj",
"test\\WebSites\\ApiExplorerWebSite\\ApiExplorerWebSite.csproj",
"test\\WebSites\\VersioningWebSite\\VersioningWebSite.csproj",
"test\\WebSites\\TagHelpersWebSite\\TagHelpersWebSite.csproj",
"test\\WebSites\\FilesWebSite\\FilesWebSite.csproj",
"test\\WebSites\\ApplicationModelWebSite\\ApplicationModelWebSite.csproj",
"test\\WebSites\\HtmlGenerationWebSite\\HtmlGenerationWebSite.csproj",
"test\\WebSites\\ErrorPageMiddlewareWebSite\\ErrorPageMiddlewareWebSite.csproj",
"test\\WebSites\\XmlFormattersWebSite\\XmlFormattersWebSite.csproj",
"test\\WebSites\\ControllersFromServicesWebSite\\ControllersFromServicesWebSite.csproj",
"test\\WebSites\\ControllersFromServicesClassLibrary\\ControllersFromServicesClassLibrary.csproj",
"test\\WebSites\\CorsWebSite\\CorsWebSite.csproj",
"samples\\MvcSandbox\\MvcSandbox.csproj",
"test\\WebSites\\SimpleWebSite\\SimpleWebSite.csproj",
"test\\WebSites\\SecurityWebSite\\SecurityWebSite.csproj",
"test\\WebSites\\RazorPagesWebSite\\RazorPagesWebSite.csproj",
"benchmarks\\Microsoft.AspNetCore.Mvc.Performance\\Microsoft.AspNetCore.Mvc.Performance.csproj",
"test\\WebSites\\RazorBuildWebSite\\RazorBuildWebSite.csproj",
"test\\WebSites\\RazorBuildWebSite.Views\\RazorBuildWebSite.Views.csproj",
"Mvc.Analyzers\\src\\Microsoft.AspNetCore.Mvc.Analyzers.csproj",
"Mvc.Analyzers\\test\\Mvc.Analyzers.Test.csproj",
"test\\WebSites\\RazorPagesClassLibrary\\RazorPagesClassLibrary.csproj",
"shared\\Mvc.Views.TestCommon\\Microsoft.AspNetCore.Mvc.Views.TestCommon.csproj",
"Mvc.Api.Analyzers\\test\\Mvc.Api.Analyzers.Test.csproj",
"Mvc.Api.Analyzers\\src\\Microsoft.AspNetCore.Mvc.Api.Analyzers.csproj",
"test\\WebSites\\GenericHostWebSite\\GenericHostWebSite.csproj",
"Mvc\\src\\Microsoft.AspNetCore.Mvc.csproj",
"Mvc\\test\\Microsoft.AspNetCore.Mvc.Test.csproj",
"Mvc.Abstractions\\src\\Microsoft.AspNetCore.Mvc.Abstractions.csproj",
"Mvc.Abstractions\\test\\Microsoft.AspNetCore.Mvc.Abstractions.Test.csproj",
"Mvc.ApiExplorer\\src\\Microsoft.AspNetCore.Mvc.ApiExplorer.csproj",
"Mvc.ApiExplorer\\test\\Microsoft.AspNetCore.Mvc.ApiExplorer.Test.csproj",
"Mvc.Core\\src\\Microsoft.AspNetCore.Mvc.Core.csproj",
"Mvc.Core\\test\\Microsoft.AspNetCore.Mvc.Core.Test.csproj",
"Mvc.Cors\\src\\Microsoft.AspNetCore.Mvc.Cors.csproj",
"Mvc.Cors\\test\\Microsoft.AspNetCore.Mvc.Cors.Test.csproj",
"Mvc.DataAnnotations\\src\\Microsoft.AspNetCore.Mvc.DataAnnotations.csproj",
"Mvc.DataAnnotations\\test\\Microsoft.AspNetCore.Mvc.DataAnnotations.Test.csproj",
"Mvc.Formatters.Json\\src\\Microsoft.AspNetCore.Mvc.Formatters.Json.csproj",
"Mvc.Formatters.Xml\\src\\Microsoft.AspNetCore.Mvc.Formatters.Xml.csproj",
"Mvc.Formatters.Xml\\test\\Microsoft.AspNetCore.Mvc.Formatters.Xml.Test.csproj",
"Mvc.Localization\\src\\Microsoft.AspNetCore.Mvc.Localization.csproj",
"Mvc.Localization\\test\\Microsoft.AspNetCore.Mvc.Localization.Test.csproj",
"Mvc.Razor\\src\\Microsoft.AspNetCore.Mvc.Razor.csproj",
"Mvc.Razor\\test\\Microsoft.AspNetCore.Mvc.Razor.Test.csproj",
"Mvc.RazorPages\\src\\Microsoft.AspNetCore.Mvc.RazorPages.csproj",
"Mvc.RazorPages\\test\\Microsoft.AspNetCore.Mvc.RazorPages.Test.csproj",
"Mvc.TagHelpers\\src\\Microsoft.AspNetCore.Mvc.TagHelpers.csproj",
"Mvc.TagHelpers\\test\\Microsoft.AspNetCore.Mvc.TagHelpers.Test.csproj",
"Mvc.ViewFeatures\\src\\Microsoft.AspNetCore.Mvc.ViewFeatures.csproj",
"Mvc.ViewFeatures\\test\\Microsoft.AspNetCore.Mvc.ViewFeatures.Test.csproj",
"test\\Mvc.FunctionalTests\\Microsoft.AspNetCore.Mvc.FunctionalTests.csproj",
"test\\Mvc.IntegrationTests\\Microsoft.AspNetCore.Mvc.IntegrationTests.csproj",
"shared\\Mvc.TestDiagnosticListener\\Microsoft.AspNetCore.Mvc.TestDiagnosticListener.csproj",
"Mvc.Testing\\src\\Microsoft.AspNetCore.Mvc.Testing.csproj",
"shared\\Mvc.Core.TestCommon\\Microsoft.AspNetCore.Mvc.Core.TestCommon.csproj",
"Mvc.NewtonsoftJson\\src\\Microsoft.AspNetCore.Mvc.NewtonsoftJson.csproj",
"Mvc.NewtonsoftJson\\test\\Microsoft.AspNetCore.Mvc.NewtonsoftJson.Test.csproj",
"Mvc.Razor.RuntimeCompilation\\src\\Microsoft.AspNetCore.Mvc.Razor.RuntimeCompilation.csproj",
"Mvc.Razor.RuntimeCompilation\\test\\Microsoft.AspNetCore.Mvc.Razor.RuntimeCompilation.Test.csproj",
"test\\WebSites\\RazorBuildWebSite.PrecompiledViews\\RazorBuildWebSite.PrecompiledViews.csproj",
"Mvc.Components.Prerendering\\src\\Microsoft.AspNetCore.Mvc.Components.Prerendering.csproj",
"Mvc.Components.Prerendering\\test\\Microsoft.AspNetCore.Mvc.Components.Prerendering.Test.csproj",
]
}
}
0% 加载中 .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册