Custom Adapter with parameters and injected service not working

I have implemented a custom data adapter as a component to pass parameters as indicated in instructions. I have used Query and inherits DataAdapter<T>. My component is called but the read method isn't. Any help would be appreciated.

DistrictSelect.razor:

<SfGrid TValue="District"
        Query="_query"
        ID="_gridRef"
        @ref="_gridRef"
        Width="550px"
        AllowPaging="true"
        AllowSorting="true"
        AllowExcelExport="true">
    <SfDataManager Adaptor="Adaptors.CustomAdaptor">
        <DistrictDataAdapter />
    </SfDataManager>
    <GridPageSettings PageSize="@_pageSize" /> 
    <GridEvents TValue="District" RowSelected="RowSelectHandler" />
    <GridTemplates>
        <ToolbarTemplate Context="toolbarContext">
            <SfToolbar>
                <ToolbarItems>
                    <ToolbarItem Align="ItemAlign.Left" Type="ItemType.Input">
                        <Template>
                            <div style="align-items: center;">
                                <h2>Districts</h2>
                            </div>
                        </Template>
                    </ToolbarItem>
                    <ToolbarItem Type="ItemType.Input" Width="300">
                        <Template>
                            <div style="width: 300px; position: absolute; right: 0;">
                            <span class="material-icons" style="vertical-align: bottom;">search</span>
                            <SfTextBox Input="GridSearch" Placeholder="Search" />
                            </div>
                        </Template>
                    </ToolbarItem>
                </ToolbarItems>
            </SfToolbar>
        </ToolbarTemplate>
    </GridTemplates>    
    <GridColumns>
        <GridColumn Field="@nameof(District.DistrictName)" HeaderText="District Name" Width="300px" TextAlign="TextAlign.Left" />
        <GridColumn Field="@nameof(District.StateID)" HeaderText="State" Width="100px" TextAlign="TextAlign.Left" />
    </GridColumns>

DistrictSelect.razor.cs:
    protected override async Task OnInitializedAsync()
    {
        var authState = await StateProvider.GetAuthenticationStateAsync();
        _userCP = authState.User;
        _userID = _userCP.FindFirst(ClaimTypes.NameIdentifier)?.Value ?? string.Empty;

        var IsAuthenticated = authState.User.Identity?.IsAuthenticated ?? false;

        if (!IsAuthenticated)
        {
            return;
        }

        _query = new Query().AddParams("userID", _userID).AddParams("userCP", _userCP);

        await base.OnInitializedAsync();
    }

DistrictDataAdapter.razor:
@inherits DataAdaptor<GoPlatformService> <CascadingValue Value="@this"> @ChildContent </CascadingValue> @code { [Parameter] [JsonIgnore] public RenderFragment? ChildContent { get; set; } private string? _searchString = null; private string? _userID = string.Empty; private ClaimsPrincipal? _userCP = null; public override async Task<object> ReadAsync(DataManagerRequest dataManagerRequest, string? key = null) { if (dataManagerRequest.Params != null && dataManagerRequest.Params.Count > 0) { _userID = dataManagerRequest.Params["userID"]?.ToString(); _userCP = dataManagerRequest.Params["userCP"] as ClaimsPrincipal; } if (dataManagerRequest.Where is null && dataManagerRequest.Search is null) { _searchString = null; } else if (dataManagerRequest.Where?.Count > 0 && dataManagerRequest.Where[0].predicates is not null) { _searchString = dataManagerRequest.Where[0].predicates[0].value?.ToString(); } else if (dataManagerRequest.Search?.Count > 0) { _searchString = dataManagerRequest.Search[0].Key; } var pageNumber = dataManagerRequest.Skip / dataManagerRequest.Take; PaginationSettings settings = new() { PageNumber = pageNumber, PageSize = dataManagerRequest.Take, IsAscending = true, OrderByColumn = nameof(District.DistrictName), SearchString = _searchString }; DistrictsWithCount result; if (_userCP!.IsInRole(Roles.Admin) || string.IsNullOrEmpty(_userID)) { result = await Service.GetPaginatedDistricts(settings); } else { settings.AspNetUserID = _userID; result = await Service.GetPaginatedDistrictsByAspNetUserID(settings); } return dataManagerRequest.RequiresCounts ? new DataResult() { Result = result.Districts, Count = result.Total } : result.Districts; }

5 Replies

PS Prathap Senthil Syncfusion Team March 18, 2026 11:56 AM UTC

Hi Claudia Irvine,


Based on the details you shared about your project, the ReadAsync method is not being called on your end. We also attempted to reproduce the issue on our side, but we were unable to replicate it. Kindly refer to the attached sample and screenshot for your reference.


  • To help us analyze the issue effectively, please share a simple, reproducible sample along with duplicate data . This will allow us to identify the problem and provide a resolution quickly.
  • Could you also share your attempt to replicate the issue using the attached sample?

The above-requested details will be very helpful for us to validate the reported query at our end and provide the solution as early as possible.


Sample: Check the attachment.


Screenshot:


Grid UG: Bind data and perform CRUD actions with CustomAdaptor in Syncfusion Blazor DataGrid

Regards,
Prathap Senthil


Attachment: DataGrid_CutsomAdaptor_bdd56705.zip


CI Claudia Irvine March 18, 2026 08:24 PM UTC

I changed the query to pass a bool if the user was an admin instead of trying to pass the ClaimsPrincipal. That worked. Passing a ClaimPrincipal in the query did not.



PS Prathap Senthil Syncfusion Team March 19, 2026 02:05 PM UTC

Thanks for the update.


We are happy to hear that the reported issue regarding passing a boolean value in the query has been resolved. However, after further validation on our end, we found that ClaimsPrincipal is a complex .NET object (containing identities, claims, and authentication types) and is not JSON‑serializable. Because of this, it cannot be reliably transferred through the query parameters. The recommended approach is to pass only simple, JSON‑friendly values such as userId, userName, or roles as a comma‑separated string. If you need to pass a “user context,” please use a small DTO that includes only primitive types, strings, or arrays—not a ClaimsPrincipal. Therefore, based on your update, we suggest continuing to use the boolean variable approach to achieve your requirement on your end.



CI Claudia Irvine March 19, 2026 02:10 PM UTC

Thank you for the clarification. I will keep that in mind in my future grid designs.



NP Naveen Palanivel Syncfusion Team March 20, 2026 05:55 AM UTC

Hi Claudia Irvine,


Welcome. We are glad to hear that the previous response was helpful.

Kindly get back to us if you have further queries. As always we will be assist you.


Regards,
Naveen


Loader.
Up arrow icon