【问题标题】:Cast object of (string, multidimensional-array) as JSON result in C# Dotnet 5.0将(字符串,多维数组)的对象转换为 JSON 结果在 C# Dotnet 5.0
【发布时间】:2021-04-06 13:52:57
【问题描述】:

我有一个具有以下结构/类的控制器:

// 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(类型 typeToConvert,JsonSerializerOptions 选项)
在 System.Text.Json.Serialization.JsonConverterFactory.GetConverterInternal(类型 typeToConvert,JsonSerializerOptions 选项)
在 System.Text.Json.JsonSerializerOptions.GetConverter(类型 typeToConvert)

如何使用(字符串,多维数组)序列化对象?另外我有一个期望结果的反应应用程序,字符串也将被序列化(有 \n\n \r ....),是客户端应用程序反序列化它的工作还是我需要找到一种返回非序列化 JSON 对象的方法?

【问题讨论】:

  • 您是否有现有的格式可以匹配(请编辑)?锯齿状数组可能是这里的解决方案

标签: c# asp.net-core asp.net5


【解决方案1】:

问题实际上是您的int[,] 类型。例如,您可以将多维数组替换为 int[][]

其实下面的sn-p会抛出和你类似的异常。

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, 98, 92 },  new int[] { 97, 95, 45 }, };

这可序列化为:

[[99,98,92],[97,95,45]]

【讨论】:

    【解决方案2】:

    根据How to serialize and deserialize (marshal and unmarshal) JSON in .NETSystem.Text.Json不支持多维数组:

    支持的类型包括:

    • .NET 基元映射到 JavaScript 基元,例如数字类型、字符串和布尔值。
    • 用户定义的普通旧 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;
                    }
                }
            }
        }
    }
    

    【讨论】:

      猜你喜欢
      • 2014-09-23
      • 2014-05-14
      • 1970-01-01
      • 2015-11-13
      • 1970-01-01
      • 1970-01-01
      • 2013-08-29
      • 2012-02-26
      • 1970-01-01
      相关资源
      最近更新 更多