New to Telerik UI for Blazor? Download free 30-day trial

DataSourceRequest Filters not Working When You Add Reporting or Newtonsoft.Json

Environment

Product UI for Blazor
Blazor application type WebAssembly

Description

I recently added the Telerik Reporting (Web Report Designer) to my Blazor WebAssembly application.

My application has services.AddRazorPages().AddNewtonsoftJson(); on the server-side so I can work with various REST APIs and send data.

Now, when I send the DataSourceRequest from the grid to the server things break when I use filters. The same happens to DropDownList virtualization. It worked before.

Steps to Reproduce

Add the Newtonsoft JSON serialization service to your ASP.NET Core backend that also needs to process the Blazor grid requests.

//something like 

services.AddRazorPages().AddNewtonsoftJson();

// or

services.AddMvc().AddNewtonsoftJson();

Error Message

The API call from the grid returns a status code 400 or 500 with an error similar to

Could not create an instance of type Telerik.DataSource.IFilterDescriptor. Type is an interface or abstract class and cannot be instantiated. Path 'filters[0].member', line 1, position 65.

If I remove Newtonsoft JSON, other things in my project break, such as the reporting service becoming inaccessible with errors like when displaying a report:

Cannot access the Reporting REST service. (serviceUrl = '/api/reports'). Make sure the service address is correct and enable CORS if needed. (https://enable-cors.org)

Possible Cause

The core of the issue is the different serializers that are used in each case:

  • one is Newtonsoft.Json used for certain things (such as the reporting endpoints)
  • another is System.Text.Json used for others (such as the Blazor grid DataSourceRequest)

The different serializers are not 100% compatible with each other, and each has their own requirements and limitations. So, when Newtonsoft is registered as the serializer, the DataSourceRequest will break and when it is not - other things that rely on Newtosnoft will break.

Solution

Use explicit System.Text.Json serialization when needed:

  • to serialize the DataSourceRequest - make it explicit in the WASM app service:

    C#

    public async Task<DataEnvelope<WeatherForecast>> GetForecastListAsync(DataSourceRequest gridRequest)
    {
        HttpResponseMessage response = await Http.PostAsJsonAsync(
                "WeatherForecast", 
                JsonSerializer.Serialize<DataSourceRequest>(gridRequest)
        );
        . . .
    }
    
  • when deserializing it - don't let the framework deserialize with the registered serialized (Newtonsoft) but take it as a string in the action and deserialize explicitly there with System.Text.Json:

    C#

    [HttpPost]
    public async Task<DataEnvelope<WeatherForecast>> Post([FromBody] string gridRequestAsString)
    {
        DataSourceRequest gridRequest = JsonSerializer.Deserialize<DataSourceRequest>(gridRequestAsString);
        . . . 
    }
    

Suggested Workarounds

There are three other paths forward you can consider:

Notes

Telerik supports serialization of the DataSourceRequest as part of the Telerik.DataSource package (which is used by UI for Blazor) with the System.Text.Json serializer only.

In this article