4

I am writing a rest api in asp.net core 3.0 preview 8 and I was trying to serialize a System.Data.DataTable using the new "System.Text.Json" class, but in the Serialize method I receive the exception:

The collection type 'System.Data.DataRelationCollection' on 'System.Data.DataTable.ChildRelations' is not supported.

The same serialization works well using the newtonsoft json serializer.

Sample code to reproduce the problem:

var dt = new System.Data.DataTable("test");
dt.Columns.Add("Column1");
var ser=System.Text.Json.JsonSerializer.Serialize(dt);

Detailed exception:

System.NotSupportedException HResult=0x80131515 Message=The collection type 'System.Data.DataRelationCollection' on 'System.Data.DataTable.ChildRelations' is not supported. Source=System.Text.Json StackTrace: at System.Text.Json.JsonClassInfo.GetElementType(Type propertyType, Type parentType, MemberInfo memberInfo, JsonSerializerOptions options) at System.Text.Json.JsonClassInfo.CreateProperty(Type declaredPropertyType, Type runtimePropertyType, Type implementedPropertyType, PropertyInfo propertyInfo, Type parentClassType, JsonSerializerOptions options) at System.Text.Json.JsonClassInfo.AddProperty(Type propertyType, PropertyInfo propertyInfo, Type classType, JsonSerializerOptions options) at System.Text.Json.JsonClassInfo..ctor(Type type, JsonSerializerOptions options) at System.Text.Json.JsonSerializerOptions.GetOrAddClass(Type classType) at System.Text.Json.WriteStackFrame.Initialize(Type type, JsonSerializerOptions options) at System.Text.Json.JsonSerializer.WriteCore(Utf8JsonWriter writer, PooledByteBufferWriter output, Object value, Type type, JsonSerializerOptions options) at System.Text.Json.JsonSerializer.WriteCore(PooledByteBufferWriter output, Object value, Type type, JsonSerializerOptions options) at System.Text.Json.JsonSerializer.WriteCoreString(Object value, Type type, JsonSerializerOptions options) at System.Text.Json.JsonSerializer.Serialize[TValue](TValue value, JsonSerializerOptions options) at ErrorJsonMIcrosoftDataTable.Controllers.WeatherForecastController.Get() in G:\testnet\ErrorJsonMIcrosoftDataTable\ErrorJsonMIcrosoftDataTable\Controllers\WeatherForecastController.cs:line 31 at Microsoft.Extensions.Internal.ObjectMethodExecutor.Execute(Object target, Object[] parameters) at Microsoft.AspNetCore.Mvc.Infrastructure.ActionMethodExecutor.SyncObjectResultExecutor.Execute(IActionResultTypeMapper mapper, ObjectMethodExecutor executor, Object controller, Object[] arguments) at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.<g__Logged|12_1>d.MoveNext()

May you kindly help?

Thank you.

dbc
  • 104,963
  • 20
  • 228
  • 340
Fabio Pagano
  • 233
  • 3
  • 11
  • In my case, I'd be happy if I could just figure a way to ignore the `ChildRelations` property. – Auspex Nov 08 '19 at 16:05
  • Do you need to deserialize, or only serialize? Using a `JsonConverter`, serialization is much easier than deserialization. – dbc Nov 27 '19 at 05:16
  • See https://stackoverflow.com/q/59780446/8479 for a solution using `System.Text.Json` – Rory Feb 25 '22 at 19:58

1 Answers1

7

Short answer: It can't be done with System.Text.Json, at least for the time being.

If you would like to serialize System.Data.DataTable using ASP.NET Core 3.0 with what is available today, please continue reading the rest of my post for a workaround.

Workaround: First of all, you should check the "Json.NET support" of the "Migrate from ASP.NET Core 2.2 to 3.0" document from MS.

The solution has 2 steps:

  1. Add a package reference to "Microsoft.AspNetCore.Mvc.NewtonsoftJson"

  2. Add this line ".AddNewtonsoftJson()" right after "services.AddMvc()" Here is an example for Startup.cs before & after the change:

Before:

services
    .AddMvc(options =>
    {
        options.EnableEndpointRouting = false;
    })
    .SetCompatibilityVersion(CompatibilityVersion.Version_3_0)
    .AddJsonOptions(options =>
    {
        options.JsonSerializerOptions.IgnoreNullValues = true;
        options.JsonSerializerOptions.WriteIndented = true;
    });

After:

services
    .AddMvc(options =>
    {
        options.EnableEndpointRouting = false;
    })
    .AddNewtonsoftJson()
    .SetCompatibilityVersion(CompatibilityVersion.Version_3_0)
    .AddJsonOptions(options =>
    {
        options.JsonSerializerOptions.IgnoreNullValues = true;
        options.JsonSerializerOptions.WriteIndented = true;
    });
UNOPARATOR
  • 688
  • 1
  • 6
  • 18
  • 2
    How is telling the OP to go back to the old JSON serializer (which they obviously already know works), any kind of answer to the question? It's a question about how you can make the new serializer work. If you _can't_, then the answer is just "_it can't be done_", not a description of how to use a different serializer – Auspex Nov 08 '19 at 15:54
  • @Unoparator thank you, your sample code helped me so much. – Fabio Pagano Dec 17 '19 at 20:09