0

As per subject how I can optimize the json response from an EF Core entity by rounding the values?

In my example I have many number columns in a SQL Server database table (database-first approach) that are of type decimal(18,9). However, most of the data is 0.000000000 - multiplied by number of columns it generates big data load that could be a simple rounded 0 (1 char instead of 11 passed in json).

How to achieve that?

marc_s
  • 732,580
  • 175
  • 1,330
  • 1,459
kmlpwl
  • 7
  • 6
  • Do you know which library is used to convert the data to JSON? Is it System.Text.Json (likely for .NET Core 3.1) or Newtonsoft? – Christian Sep 22 '20 at 17:00
  • I'm new in .NET Core programming. How to check that? I do not explicitly provide this in the project. I think it's System.Text.Json as can't find "Newtonsoft" anywhere in the code. – kmlpwl Sep 22 '20 at 17:36

1 Answers1

1

What's going on

This is basically what happens:

HTTP Request -> API Controller -> EF Core Query -> JSON Serialization -> HTTP Response

The crucial part is the JSON Serialization. This takes arbitrary data (in your case the result of an EF Core Query) and converts it to JSON. The JSON Serialization is called under the hood by the thing that is calling your API controller's method. It's done by System.Text.Json.JsonSerializer due to the default configuration of ASP.Net core. In order to get 0.0 instead of 0.000000000 you have to change that configuration.

How to solve

To change the default JSON Serialization configuration of ASP.NET core you have to add some code to the ConfigureServices() method in your Startup.cs file:

// Inside Startup.cs

// Find services.AddControllers() and change it to
services
    .AddControllers()
    .AddJsonOptions(o => o.JsonSerializerOptions.Converters.Add(new MyDecimalConverter()));

The code above needs the MyDecimalConverter class which you need to add to your project.

public class MyDecimalConverter : JsonConverter<Decimal>
{
    public override Decimal Read(
        ref Utf8JsonReader reader,
        Type typeToConvert,
        JsonSerializerOptions options) =>
        reader.GetDecimal();

    public override void Write(
        Utf8JsonWriter writer,
        Decimal decimalValue,
        JsonSerializerOptions options) =>
        // taken from https://stackoverflow.com/a/7983330/4262276
        writer.WriteNumberValue(decimalValue / 1.0000000000000000000000000000m);
}
Christian
  • 1,250
  • 9
  • 12
  • This works out of the box :-) and thank you for giving high level overview of the flow, really appreciate it! I thought there will be easier way on the EF Core level to round the data before it will be serialized. The bottleneck i see it is a little bit slow - my "Waiting (TTFB) raised from the 2 seconds to about 10 seconds for a small table. – kmlpwl Sep 24 '20 at 12:55