I have a controller that has the following structure/classes:
// 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");
}
}
}
It seems that it's not able to serialize the Result object, I am getting the following exception:
fail: Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddleware[1]
An unhandled exception has occurred while executing the request.
System.NotSupportedException: The type 'System.Int32[,]' is not supported.
at System.Text.Json.ThrowHelper.ThrowNotSupportedException_SerializationNotSupported(Type propertyType)
at System.Text.Json.Serialization.Converters.IEnumerableConverterFactory.CreateConverter(Type typeToConvert, JsonSerializerOptions options)
at System.Text.Json.Serialization.JsonConverterFactory.GetConverterInternal(Type typeToConvert, JsonSerializerOptions options)
at System.Text.Json.JsonSerializerOptions.GetConverter(Type typeToConvert)
How do I go about serializing an object with (string, multidimensional array)? Also I have a react app that expects a result, the string is going to be serialized as well (has \n\n \r ....), is it the job for the client app to deserialize it or I need to find a way to return the JSON object as it is non-serialized?
The problem is in fact your int[,]
type. You could replace your multidimensional array by int[][]
, for example.
In fact, the snippet below throws an exception similar to yours.
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));
}
}
The exception:
Unhandled exception. System.NotSupportedException: The type 'System.Int32[,]' is not supported.
at System.Text.Json.ThrowHelper.ThrowNotSupportedException_SerializationNotSupported(Type propertyType)
...
However, if you replace the example
declaration by an int[][]
, then we can have:
var example = new int[][] { new int[] { 99, 98, 92 }, new int[] { 97, 95, 45 }, };
This is serializable to:
[[99,98,92],[97,95,45]]
According to How to serialize and deserialize (marshal and unmarshal) JSON in .NET, multi-dimensional arrays are not supported by System.Text.Json
:
Supported types include:
- .NET primitives that map to JavaScript primitives, such as numeric types, strings, and Boolean.
- User-defined plain old CLR objects (POCOs).
- One-dimensional and jagged arrays (T[][]).
- Collections and dictionaries from the following namespaces.
- System.Collections
- System.Collections.Generic
- System.Collections.Immutable
- System.Collections.Concurrent
- System.Collections.Specialized
- System.Collections.ObjectModel
So one option I could see you can do is convert your multi-dimensional array to a list:
public class Result
{
public string Document { get; set; } = "";
public IList<IList<int>> Segments { get; set; } = new List<IList<int>>();
}
Or use a jagged array:
public class Result
{
public string Document { get; set; } = "";
public int[][] Segments { get; set; } = new int[][] { };
}
UPDATE
Another alternative, if you know the dimensions of the array, is to write a custom getter/setter only for your JSON property. This example assumes the multi-dimension array has 2 as second dimension.
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;
}
}
}
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With