问题描述
我有一个具有以下结构/类的控制器:
// model
public class Result
{
public string Document { get; set; } = "";
public int[,] Segments { get; set; } = new int[,] { };
}
// controller
public class SearchController : ControllerBase {
[HttpGet]
[Route("/api/v1/[controller]")]
[Produces("application/json")]
public IActionResult Search(//metadata list)
{
try {
Result result = <service-call-returning Result object>;
return Ok(result);
} catch (Exception e) {
return BadRequest("bad");
}
}
}
它似乎无法序列化 Result 对象,我收到以下异常:
失败:Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddleware[1]
执行请求时发生未处理的异常。
System.NotSupportedException: 不支持类型“System.Int32[,]”。
在
System.Text.Json.ThrowHelper.ThrowNotSupportedException_SerializationNotSupported(Type propertyType)
在 System.Text.Json.Serialization.Converters.IEnumerableConverterFactory.CreateConverter(Type typeToConvert,JsonSerializerOptions options)
在 System.Text.Json.Serialization.JsonConverterFactory.GetConverterInternal(Type typeToConvert,JsonSerializerOptions options)
在 System.Text.Json.JsonSerializerOptions.GetConverter(Type typeToConvert)
如何使用(字符串、多维数组)序列化对象?此外,我有一个预期结果的反应应用程序,该字符串也将被序列化(具有 \n\n \r ....),是客户端应用程序反序列化它的工作还是我需要找到一种返回非序列化 JSON 对象的方法?
解决方法
问题实际上是您的 int[,]
类型。例如,您可以将多维数组替换为 int[][]
。
事实上,下面的代码段引发了与您类似的异常。
using System;
using System.Text.Json;
public class Program
{
public static void Main()
{
var example = new int[,] { { 99,98,92 },{ 97,95,45 } };
Console.WriteLine(JsonSerializer.Serialize(example));
}
}
例外:
Unhandled exception. System.NotSupportedException: The type 'System.Int32[,]' is not supported.
at System.Text.Json.ThrowHelper.ThrowNotSupportedException_SerializationNotSupported(Type propertyType)
...
但是,如果您将 example
声明替换为 int[][]
,那么我们可以:
var example = new int[][] { new int[] { 99,new int[] { 97,45 },};
这可序列化为:
[[99,92],[97,45]]
,
根据How to serialize and deserialize (marshal and unmarshal) JSON in .NET,System.Text.Json
不支持多维数组:
支持的类型包括:
- 映射到 JavaScript 基元的 .NET 基元,例如数字类型、字符串和布尔值。
- 用户定义的普通旧 CLR 对象 (POCO)。
- 一维和交错数组 (T[][])。
- 来自以下命名空间的集合和字典。
- System.Collections
- System.Collections.Generic
- System.Collections.Immutable
- System.Collections.Concurrent
- System.Collections.Specialized
- System.Collections.ObjectModel
所以我可以看到您可以做的一个选择是将您的多维数组转换为列表:
public class Result
{
public string Document { get; set; } = "";
public IList<IList<int>> Segments { get; set; } = new List<IList<int>>();
}
或者使用锯齿状数组:
public class Result
{
public string Document { get; set; } = "";
public int[][] Segments { get; set; } = new int[][] { };
}
更新
如果您知道数组的维度,另一种选择是仅为您的 JSON 属性编写自定义 getter/setter。此示例假设多维数组的第二维为 2。
public class Result
{
public string Document { get; set; } = "";
[JsonIgnore]
public int[,] Segments { get; set; } = new int[,] { };
[JsonPropertyName("segments")]
public IList<IList<int>> JsonSegments
{
get
{
var value = new List<IList<int>>();
for (int i = 0; i < Segments.Length / 2; i++)
{
value.Add(new List<int> { Segments[i,0],Segments[i,1] });
}
return value;
}
set
{
var dimension = value.Count;
Segments = new int[dimension,2];
var index = 0;
foreach (var item in value)
{
if (item.Count == 2)
{
Segments[index,0] = item[0];
Segments[index,1] = item[1];
index += 1;
}
}
}
}
}