diff --git a/blazor/datagrid/connecting-to-adaptors/odatav4-adaptor.md b/blazor/datagrid/connecting-to-adaptors/odatav4-adaptor.md index 2bbfde79ad..05e82f74c6 100644 --- a/blazor/datagrid/connecting-to-adaptors/odatav4-adaptor.md +++ b/blazor/datagrid/connecting-to-adaptors/odatav4-adaptor.md @@ -1,6 +1,6 @@ --- layout: post -title: Bind data and perform CRUD action with ODataV4Adaptor in Syncfusion Blazor DataGrid +title: Blazor DataGrid with ODataV4Adaptor| Syncfusion description: Learn about bind data and performing CRUD operations using ODataV4Adaptor in Syncfusion Blazor DataGrid. platform: Blazor control: DataGrid @@ -8,168 +8,39 @@ keywords: adaptors, ODataV4adaptor, ODataV4 adaptor, remotedata documentation: ug --- -# ODataV4Adaptor in Syncfusion® Blazor DataGrid +# OData Remote Data Binding in Syncfusion Blazor Components -The [ODataV4Adaptor](https://blazor.syncfusion.com/documentation/data/adaptors#odatav4-adaptor) in the Syncfusion® Blazor DataGrid enables seamless integration of the Grid with OData V4 services, facilitating efficient data fetching and manipulation. This guide provides detailed instructions for binding data and performing CRUD (Create, Read, Update, and Delete) actions using the `ODataV4Adaptor` in your Syncfusion® Blazor DataGrid. +The [ODataV4Adaptor](https://ej2.syncfusion.com/react/documentation/data/adaptors/odatav4-adaptor) in the Syncfusion® Blazor DataManager enables seamless integration between the Blazor DataGrid and OData V4 services by handling OData‑formatted request and response processing. It automatically converts DataGrid actions such as filtering, sorting, paging, grouping, and CRUD into OData V4 compliant query options (like `$filter`, `$orderby`, `$top`, `$skip`) and sends them to the server. The adaptor also parses the structured OData V4 JSON response, extracting the result set and count values, ensuring smooth remote data binding without custom query or response logic. -## Configuring an OData V4 Service +For complete server‑side configuration and additional implementation details, refer to the [DataManager ODataV4Adaptor documentation](https://blazor.syncfusion.com/documentation/data/adaptors), which covers endpoint setup, query processing, and best practices for integrating OData V4 services. -To configure a server with Syncfusion® Blazor DataGrid, follow these steps: +Once the project creation and backend setup are complete, the next step is to integrate the Syncfusion® Blazor DataGrid with the `ODataV4Adaptor`. -**1. Create a Blazor web app** +## Integrating Syncfusion® Blazor DataGrid to an OData V4 Service -You can create a **Blazor Web App** named **ODataV4Adaptor** using Visual Studio 2022, either via [Microsoft Templates](https://learn.microsoft.com/en-us/aspnet/core/blazor/tooling?view=aspnetcore-8.0) or the [Syncfusion® Blazor Extension](https://blazor.syncfusion.com/documentation/visual-studio-integration/template-studio). Make sure to configure the appropriate [interactive render mode](https://learn.microsoft.com/en-us/aspnet/core/blazor/components/render-modes?view=aspnetcore-8.0#render-modes) and [interactivity location](https://learn.microsoft.com/en-us/aspnet/core/blazor/tooling?view=aspnetcore-8.0&pivots=windows). - -**2. Install NuGet packages** - -Using the NuGet package manager in Visual Studio (Tools → NuGet Package Manager → Manage NuGet Packages for Solution), install the `Microsoft.AspNetCore.OData` NuGet package. - -**3. Create a model class** - -Create a new folder named **Models**. Then, add a model class named **OrdersDetails.cs** to the **Models** folder under `ODataV4Adaptor.Client` to represent the order data. - -```csharp - -using System.ComponentModel.DataAnnotations; - -namespace ODataV4Adaptor.Client.Models -{ - public class OrdersDetails - { - public static List order = new List(); - - public OrdersDetails() { } - - public OrdersDetails(int OrderID, string CustomerId, int EmployeeId, string ShipCountry) - { - this.OrderID = OrderID; - this.CustomerID = CustomerId; - this.EmployeeID = EmployeeId; - this.ShipCountry = ShipCountry; - } - - public static List GetAllRecords() - { - if (order.Count() == 0) - { - int code = 10000; - for (int i = 1; i < 10; i++) - { - order.Add(new OrdersDetails(code + 1, "ALFKI", i + 0, "Denmark")); - order.Add(new OrdersDetails(code + 2, "ANATR", i + 2, "Brazil")); - order.Add(new OrdersDetails(code + 3, "ANTON", i + 1, "Germany")); - order.Add(new OrdersDetails(code + 4, "BLONP", i + 3, "Austria")); - order.Add(new OrdersDetails(code + 5, "BOLID", i + 4, "Switzerland")); - code += 5; - } - } - return order; - } - - [Key] - public int OrderID { get; set; } - public string? CustomerID { get; set; } - public int? EmployeeID { get; set; } - public string? ShipCountry { get; set; } - } -} - -``` - -**4. Build the Entity Data Model** - -To construct the Entity Data Model for your OData service, use the `ODataConventionModelBuilder` to define the model’s structure in the `Program.cs` file of the `ODataV4Adaptor` project. Start by creating an instance of the `ODataConventionModelBuilder`, and then register the entity set **Orders** using the `EntitySet` method, where `OrdersDetails` represents the CLR type containing order details. - -```csharp -// Create an ODataConventionModelBuilder to build the OData model. -var modelBuilder = new ODataConventionModelBuilder(); - -// Register the "Grid" entity set with the OData model builder. -modelBuilder.EntitySet("Grid"); -``` - -**5. Register the OData services** - -After building the Entity Data Model, register the OData services in the `Program.cs` file of your application. Follow these steps: - -```cs -// Add controllers with OData support to the service collection. -builder.Services.AddControllers().AddOData( - options => options - .Count() - .AddRouteComponents("odata", modelBuilder.GetEdmModel()) -); -``` - -**6. Create an API controller** - -Create an API controller (aka, **GridController.cs**) file under the **Controllers** folder within the `ODataV4Adaptor` project. This controller facilitates data communication with the Blazor DataGrid. - -```csharp - -using Microsoft.AspNetCore.Mvc; -using Microsoft.AspNetCore.OData.Query; -using ODataV4Adaptor.Models; - -namespace ODataV4Adaptor.Controllers -{ - [ApiController] - [Route("[controller]")] - public class GridController : ControllerBase - { - /// - /// Retrieves all records available from the data source. - /// - /// - /// Returns list of records. - /// - [HttpGet] - [EnableQuery] - public IActionResult Get() - { - var data = OrdersDetails.GetAllRecords().AsQueryable(); - return Ok(data); - } - } -} - -``` - -**7. Register controllers in `Program.cs`** - -Add the following lines in the `Program.cs` file under the `ODataV4Adaptor` project to register controllers: - -```csharp -// Register controllers in the service container. -builder.Services.AddControllers(); - -// Map controller routes. -app.MapControllers(); -``` - -**8. Run the application:** - -Run the application in Visual Studio. It will be hosted at the URL **https://localhost:xxxx**. - -After running the application, you can verify that the server-side API controller successfully returns the order data at the URL **https://localhost:xxxx/odata/grid** (where **xxxx** represents the port number). - -![ODataV4Adaptor Data](../images/odatav4-adaptors-data.png) +To integrate the Syncfusion® Blazor DataGrid into your project using Visual Studio, follow the below steps: -## Connecting Syncfusion® Blazor DataGrid to an OData V4 Service +### Step 1: Install Syncfusion® Blazor DataGrid and Themes NuGet packages** -To integrate the Syncfusion® Blazor DataGrid into your project using Visual Studio, follow the below steps: +**Method 1: Using NuGet Package Manager UI** -**1. Install Syncfusion® Blazor DataGrid and Themes NuGet packages** +To add the Blazor DataGrid to the app, open the NuGet Package Manager in Visual Studio (*Tools → NuGet Package Manager → Manage NuGet Packages for Solution*) for the `ODataV4Adaptor.Client` project, search and install + - **[Syncfusion.Blazor.Grid](https://www.nuget.org/packages/Syncfusion.Blazor.Grid/)** (version {{site.blazorversion}}) + - **[Syncfusion.Blazor.Themes](https://www.nuget.org/packages/Syncfusion.Blazor.Themes/)** (version {{site.blazorversion}}). -To add the Blazor DataGrid to the app, open the NuGet Package Manager in Visual Studio (*Tools → NuGet Package Manager → Manage NuGet Packages for Solution*) for the `ODataV4Adaptor.Client` project, search and install [Syncfusion.Blazor.Grid](https://www.nuget.org/packages/Syncfusion.Blazor.Grid/) and [Syncfusion.Blazor.Themes](https://www.nuget.org/packages/Syncfusion.Blazor.Themes/). +**Method 2: Using Package Manager Console** Alternatively, use the following Package Manager commands: ```powershell -Install-Package Syncfusion.Blazor.Grid -Version {{ site.releaseversion }} -Install-Package Syncfusion.Blazor.Themes -Version {{ site.releaseversion }} +Install-Package Syncfusion.Blazor.Grid -Version {{ site.blazorversion}} +Install-Package Syncfusion.Blazor.Themes -Version {{ site.blazorversion}} ``` +All required packages are now installed. + +If your Blazor Web App uses `WebAssembly` or `Auto` render modes, install the Syncfusion® Blazor NuGet packages in the client project. + > Syncfusion® Blazor components are available on [nuget.org](https://www.nuget.org/packages?q=syncfusion.blazor). Refer to the [NuGet packages](https://blazor.syncfusion.com/documentation/nuget-packages) topic for a complete list of available packages. **2. Register Syncfusion® Blazor service** @@ -191,38 +62,38 @@ builder.Services.AddSyncfusionBlazor(); **3. Add stylesheet and script resources** -Include the theme stylesheet and script references in the **~/Components/App.razor** file. +Add the Syncfusion stylesheet and scripts in the **~/Components/App.razor**. Find the `` section and add: ```html - - .... - - -.... - - .... - - + + + + + ``` -> * Refer to the [Blazor Themes](https://blazor.syncfusion.com/documentation/appearance/themes) topic for various methods to include themes (e.g., Static Web Assets, CDN, or CRG). -> * Set the render mode to **InteractiveServer** or **InteractiveAuto** in your Blazor Web App configuration. +For this project, the **bootstrap5** theme is used. A different theme can be selected or customized based on project requirements. Refer to the [Syncfusion Blazor Components Appearance](https://blazor.syncfusion.com/documentation/appearance/themes) documentation to learn more about theming and customization options. + +Syncfusion components are now configured and ready to use. For additional guidance, refer to the Grid component's [getting‑started](https://blazor.syncfusion.com/documentation/datagrid/getting-started-with-web-app) documentation. + +### Step 2: Update the Blazor DataGrid with ODataV4Adaptor. -**4. Add Blazor DataGrid and configure with server** +DSyncfusion® Blazor DataGrid integration with OData‑based backend services is enabled through the `ODataV4Adaptor`, which connects the Syncfusion `SfDataManager` to OData V4 REST endpoints. It automatically converts DataGrid actions such as paging, sorting, filtering, searching, and grouping into OData‑compliant query parameters that the server can process. This makes it ideal for applications built on OData V4, offering seamless server‑side data operations without the need for custom request or response handling. To connect the Blazor DataGrid to an OData V4 service, use the [Url](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.DataManager.html#Syncfusion_Blazor_DataManager_Url) property of [SfDataManager](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.DataManager.html) and set the [Adaptor](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.DataManager.html#Syncfusion_Blazor_DataManager_Adaptor) property to `Adaptors.ODataV4Adaptor`. Update the **Index.razor** file as follows. The `SfDataManager` offer multiple adaptor options to connect with remote databases based on an API service. Below is an example of the [ODataV4Adaptor](https://blazor.syncfusion.com/documentation/data/adaptors#odatav4-adaptor), which works with an OData V4 API that returns data in the expected `value` and `@odata.context` format. -{% tabs %} -{% highlight razor tabtitle="Index.razor"%} +```cshtml + +@page "/" @using Syncfusion.Blazor.Grids @using Syncfusion.Blazor.Data @using ODataV4Adaptor.Client.Models - + @@ -230,10 +101,19 @@ The `SfDataManager` offer multiple adaptor options to connect with remote databa + + + ``` -{% endhighlight %} - -{% highlight cs tabtitle="GridController.cs" %} +### Step 3: Implement the Endpoints for WebAPIAdaptor + +DataGrid integration with OData‑based backend services is enabled through the `ODataV4Adaptor`, which connects the Syncfusion `SfDataManager` to OData V4 REST endpoints. It automatically converts DataGrid actions such as paging, sorting, filtering and searching into OData‑compliant query parameters that the server can process. This makes it ideal for applications built on OData V4, offering seamless server‑side data operations without the need for custom request or response handling. + +By delegating these operations to the server rather than executing them in the browser, the DataGrid ensures that only the required data is retrieved for each request. + +Open the file named **Controllers/GridController.cs** and use the following structure: + +```csharp using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.OData.Query; @@ -261,24 +141,50 @@ namespace ODataV4Adaptor.Controllers } } -{% endhighlight %} -{% endtabs %} - -> Replace https://localhost:xxxx/odata/grid with the actual URL of your API endpoint that provides the data in a consumable format (e.g., JSON). - -**5. Run the application** +``` -When you run the application, the Blazor DataGrid will display data fetched from the OData V4 service. +> The DataGrid sends GET requests with OData V4 query options such as `$filter`, `$orderby`, `$top`, and `$skip`, and the server is expected to return an OData‑compliant JSON response containing the total record count (`@odata.count`) and the data collection (`value`) for proper data binding and paging. + +### Step 4: Running the Application + +**Build the Application** -![ODataV4Adaptor Data](../images/blazor-odatav4-adaptors.gif) +1. Open PowerShell or your terminal. +2. Navigate to the project directory. +3. Build the application: -> Replace `https://localhost:xxxx/odata/` with the actual URL of your OData V4 service. +```powershell +dotnet build +``` -## Handling searching operation +**Run the Application** -By default, ODataV4 does not support global search, which is the ability to search across all fields simultaneously. To overcome this limitation, Syncfusion® provides a search fallback mechanism that allows you to implement a global search experience using the `EnableODataSearchFallback` option. +Execute the following command: -To enable search operations in your web application using OData, you first need to configure OData support in your service collection. This involves adding the `Filter` method within the OData setup, allowing you to filter data based on specified criteria. Once enabled, clients can utilize the **$filter** query option in their requests to search for specific data entries. +```powershell +dotnet run +``` + +The application will start, and the console will display the local URL (typically `http://localhost:5175` or `https://localhost:5001`). + +**Access the Application** + +1. Open a web browser. +2. Navigate to the URL displayed in the console. +3. The DataGrid application is now running and ready to use. + +## Server-side data operations + +The Syncfusion® Blazor DataGrid optimizes large datasets by relying on server‑side data operations such as filtering, sorting, and paging rather than processing everything in the browser. The `Syncfusion.EJ2.AspNet.Core` package supports this approach by providing built‑in methods that efficiently handle these operations on the server, ensuring smooth performance even with heavy data loads. + +DataGrid optimizes large datasets by relying on server‑side data operations such as filtering, sorting, and paging rather than processing everything in the browser. The `Syncfusion.EJ2.AspNet.Core` package supports this approach by providing built‑in methods that efficiently handle these operations on the server, ensuring smooth performance even with heavy data loads. + +### Handling Paging operation + +* Ensure the DataGrid has paging enabled with `AllowPaging="true"`. +* To implement paging operations in your web application using OData, you can utilize the `SetMaxTop` method within your OData setup to limit the maximum number of records that can be returned per request. While you configure the maximum limit, clients can utilize the **$skip** and **$top** query options in their requests to specify the number of records to skip and the number of records to take, respectively. + +Utilize `SetMaxTop()` method in **Program.cs** to establish maximum records per request limit. {% tabs %} {% highlight cs tabtitle="program.cs" %} @@ -292,27 +198,32 @@ var modelBuilder = new ODataConventionModelBuilder(); // Register the "Grid" entity set with the OData model builder. modelBuilder.EntitySet("Grid"); +var recordCount= OrdersDetails.GetAllRecords().Count; + // Add services to the container. + // Add controllers with OData support to the service collection. builder.Services.AddControllers().AddOData( options => options // Enables $count query option to retrieve total record count. .Count() - // Enables $filter query option to allow searching based on field values. - .Filter() - .AddRouteComponents("odata", modelBuilder.GetEdmModel() -) + // Limits the maximum number of records returned using $top. + .SetMaxTop(recordCount) + .AddRouteComponents( + "odata", + modelBuilder.GetEdmModel() + ) ); {% endhighlight %} -{% highlight razor tabtitle="Index.razor"%} +{% highlight razor tabtitle="Index.razor" %} @using Syncfusion.Blazor.Grids @using Syncfusion.Blazor.Data @using ODataV4Adaptor.Client.Models - - + + @@ -320,28 +231,18 @@ builder.Services.AddControllers().AddOData( -@code { - public SfDataManager? DataManager { get; set; } - protected override void OnAfterRender(bool firstRender) - { - base.OnAfterRender(firstRender); - if (DataManager?.DataAdaptor is ODataV4Adaptor odataAdaptor) - { - RemoteOptions options = odataAdaptor.Options; - options.EnableODataSearchFallback = true; - odataAdaptor.Options = options; - } - } -} {% endhighlight %} {% endtabs %} -![ODataV4Adaptor - Searching](../images/odatav4-adaptor-searching.png) +![ODataV4Adaptor - Paging](../images/odatav4-adaptor-paging.png) -## Handling filtering operation +### Handling Filtering operation -To enable filtering operations in your web application using OData, you first need to configure OData support in your service collection. This involves adding the `Filter` method within the OData setup, allowing you to filter data based on specified criteria. Once enabled, clients can utilize the **$filter** query option in their requests to retrieve specific data entries. +* Add the [AllowFiltering](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Grids.SfGrid-1.html#Syncfusion_Blazor_Grids_SfGrid_1_AllowFiltering) property to the ``. +* To enable filtering operations in your web application using OData, you first need to configure OData support in your service collection. This involves adding the `Filter` method within the OData setup, allowing you to filter data based on specified criteria. Once enabled, clients can utilize the **$filter** query option in their requests to retrieve specific data entries. + +Verify **Program.cs** includes `.Filter()` method in OData configuration. {% tabs %} {% highlight cs tabtitle="program.cs" %} @@ -367,14 +268,14 @@ builder.Services.AddControllers().AddOData( ); {% endhighlight %} -{% highlight razor tabtitle="Index.razor"%} +{% highlight razor tabtitle="Index.razor" %} @using Syncfusion.Blazor.Grids @using Syncfusion.Blazor.Data @using ODataV4Adaptor.Client.Models - + @@ -392,9 +293,14 @@ builder.Services.AddControllers().AddOData( **Multi column filtering** ![Multi column filtering](../images/odatav4-adaptor-multi-filtering.png) -## Handling sorting operation +### Handling Searching operation + +* Ensure the toolbar includes the "Search" item. +* By default, ODataV4 does not support global search, which is the ability to search across all fields simultaneously. To overcome this limitation, Syncfusion® provides a search fallback mechanism that allows you to implement a global search experience using the `EnableODataSearchFallback` option. -To enable sorting operations in your web application using OData, you first need to configure OData support in your service collection. This involves adding the `OrderBy` method within the OData setup, allowing you to sort data based on specified criteria. Once enabled, clients can utilize the **$orderby** query option in their requests to sort data entries according to the desired attributes. +To enable search operations in your web application using OData, you first need to configure OData support in your service collection. This involves adding the `Filter` method within the OData setup, allowing you to filter data based on specified criteria. Once enabled, clients can utilize the **$filter** query option in their requests to search for specific data entries. + +Search functionality requires `Filter()` method support (previously configured in **Program.cs** during OData setup). {% tabs %} {% highlight cs tabtitle="program.cs" %} @@ -409,26 +315,26 @@ var modelBuilder = new ODataConventionModelBuilder(); modelBuilder.EntitySet("Grid"); // Add services to the container. - // Add controllers with OData support to the service collection. builder.Services.AddControllers().AddOData( options => options // Enables $count query option to retrieve total record count. .Count() - // Enables $orderby query option to allow sorting based on field values. - .OrderBy() - .AddRouteComponents("odata", modelBuilder.GetEdmModel()) + // Enables $filter query option to allow searching based on field values. + .Filter() + .AddRouteComponents("odata", modelBuilder.GetEdmModel() +) ); {% endhighlight %} -{% highlight razor tabtitle="Index.razor"%} +{% highlight razor tabtitle="Index.razor" %} @using Syncfusion.Blazor.Grids @using Syncfusion.Blazor.Data @using ODataV4Adaptor.Client.Models - - + + @@ -436,19 +342,29 @@ builder.Services.AddControllers().AddOData( +@code { + public SfDataManager? DataManager { get; set; } + protected override void OnAfterRender(bool firstRender) + { + base.OnAfterRender(firstRender); + if (DataManager?.DataAdaptor is ODataV4Adaptor odataAdaptor) + { + RemoteOptions options = odataAdaptor.Options; + options.EnableODataSearchFallback = true; + odataAdaptor.Options = options; + } + } +} {% endhighlight %} {% endtabs %} -**Single column sorting** -![Single column sorting](../images/odatav4-adaptor-sorting.png) - -**Multi column sorting** -![Multi column sorting](../images/odatav4-adaptor-multi-sorting.png) +![ODataV4Adaptor - Searching](../images/odatav4-adaptor-searching.png) -## Handling paging operation +### Handling Sorting operation -To implement paging operations in your web application using OData, you can utilize the `SetMaxTop` method within your OData setup to limit the maximum number of records that can be returned per request. While you configure the maximum limit, clients can utilize the **$skip** and **$top** query options in their requests to specify the number of records to skip and the number of records to take, respectively. +* Add the [AllowSorting](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Grids.SfGrid-1.html#Syncfusion_Blazor_Grids_SfGrid_1_AllowSorting) property to the ``. +* To enable sorting operations in your web application using OData, you first need to configure OData support in your service collection. This involves adding the `OrderBy` method within the OData setup, allowing you to sort data based on specified criteria. Once enabled, clients can utilize the **$orderby** query option in their requests to sort data entries according to the desired attributes. {% tabs %} {% highlight cs tabtitle="program.cs" %} @@ -462,8 +378,6 @@ var modelBuilder = new ODataConventionModelBuilder(); // Register the "Grid" entity set with the OData model builder. modelBuilder.EntitySet("Grid"); -var recordCount= OrdersDetails.GetAllRecords().Count; - // Add services to the container. // Add controllers with OData support to the service collection. @@ -471,22 +385,19 @@ builder.Services.AddControllers().AddOData( options => options // Enables $count query option to retrieve total record count. .Count() - // Limits the maximum number of records returned using $top. - .SetMaxTop(recordCount) - .AddRouteComponents( - "odata", - modelBuilder.GetEdmModel() - ) + // Enables $orderby query option to allow sorting based on field values. + .OrderBy() + .AddRouteComponents("odata", modelBuilder.GetEdmModel()) ); {% endhighlight %} -{% highlight razor tabtitle="Index.razor"%} +{% highlight razor tabtitle="Index.razor" %} @using Syncfusion.Blazor.Grids @using Syncfusion.Blazor.Data @using ODataV4Adaptor.Client.Models - + @@ -499,13 +410,43 @@ builder.Services.AddControllers().AddOData( {% endhighlight %} {% endtabs %} -![ODataV4Adaptor - Paging](../images/odatav4-adaptor-paging.png) +**Single column sorting** + +Click "Customer ID" column header to sort by "CustomerID" field. + +![Single column sorting](../images/odatav4-adaptor-sorting.png) + +**Multi column sorting** + +Hold the Ctrl key and click "Employee ID" followed by "Customer ID" to establish hierarchical sort (primary sort by "Customer ID", secondary sort by "Employee ID" within each "Customer ID" group). + +![Multi column sorting](../images/odatav4-adaptor-multi-sorting.png) + +**Sort indicator legend:** +- ↑ (Up arrow): Indicates ascending sort direction +- ↓ (Down arrow): Indicates descending sort direction +- Numeric indicator (1, 2, 3): Displays sort priority in multi-column sorting scenarios. + +The DataGrid has now been successfully created with including paging, sorting, filtering. the next step is to enabling CRUD operations. ## Handling CRUD operations -To manage CRUD (Create, Read, Update, and Delete) operations using the ODataV4Adaptor, follow the provided guide for configuring the Syncfusion® DataGrid for [editing](https://blazor.syncfusion.com/documentation/datagrid/editing) and utilize the sample implementation of the `GridController` in your server application. This controller handles HTTP requests for CRUD operations, including GET, POST, PATCH, and DELETE. +To manage CRUD (Create, Read, Update, and Delete) operations using the ODataV4Adaptor, follow the provided guide for configuring the Syncfusion® DataGrid for [Editing](https://blazor.syncfusion.com/documentation/datagrid/editing) and utilize the sample implementation of the `GridController` in your server application. + +To enable CRUD operations in the DataGrid within your application, follow these steps. In the example below, the inline edit [Mode](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Grids.GridEditSettings.html#Syncfusion_Blazor_Grids_GridEditSettings_Mode) is enabled, and the [Toolbar](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Grids.SfGrid-1.html#Syncfusion_Blazor_Grids_SfGrid_1_Toolbar) property is configured to display toolbar items for editing. -To enable CRUD operations in the Grid within your application, follow these steps. In the example below, the inline edit [Mode](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Grids.GridEditSettings.html#Syncfusion_Blazor_Grids_GridEditSettings_Mode) is enabled, and the [Toolbar](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Grids.SfGrid-1.html#Syncfusion_Blazor_Grids_SfGrid_1_Toolbar) property is configured to display toolbar items for editing. +**CRUD works with OData:** + +This controller handles HTTP requests for CRUD operations, including GET, POST, PATCH, and DELETE. + +| Operation | HTTP Method | URL Example | Description | +|-----------|-------------|-------------|-------------| +| **Read** | GET | `/odata/Grid` | Get all records. | +| **Create** | POST | `/odata/Grid` | Add a new record. | +| **Update** | PATCH | `/odata/Grid(10001)` | Update record with key "10001". | +| **Delete** | DELETE | `/odata/Grid(10001)` | Delete record with key "10001". | + +To enable CRUD operations using the `ODataV4Adaptor` in the DataGrid, follow the steps below: {% tabs %} {% highlight razor tabtitle="Index.razor" %} @@ -515,7 +456,7 @@ To enable CRUD operations in the Grid within your application, follow these step @using ODataV4Adaptor.Client.Models - + @@ -528,7 +469,7 @@ To enable CRUD operations in the Grid within your application, follow these step {% endhighlight %} {% endtabs %} -> Normal/Inline editing is the default edit [Mode](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Grids.GridEditSettings.html#Syncfusion_Blazor_Grids_GridEditSettings_Mode) for the Grid. To enable CRUD operations, ensure that the [IsPrimaryKey](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Grids.GridColumn.html#Syncfusion_Blazor_Grids_GridColumn_IsPrimaryKey) property is set to **true** for a specific Grid column, ensuring that its value is unique. +> Normal/Inline editing is the default edit [Mode](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Grids.GridEditSettings.html#Syncfusion_Blazor_Grids_GridEditSettings_Mode) for the DataGrid. To enable CRUD operations, ensure that the [IsPrimaryKey](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Grids.GridColumn.html#Syncfusion_Blazor_Grids_GridColumn_IsPrimaryKey) property is set to **true** for a specific DataGrid column, ensuring that its value is unique. **Insert Record:** @@ -641,4 +582,78 @@ public IActionResult Delete(int key) ![Delete Record](../images/odatav4-adaptor-delete-record.png) -Please find the sample in this [GitHub location](https://github.com/SyncfusionExamples/Binding-data-from-remote-service-to-blazor-data-grid/tree/master/ODataV4Adaptor). \ No newline at end of file +**Controller method breakdown:** + +- **Get()**: Returns all orders; `[EnableQuery]` allows OData filtering/sorting. +- **Get(int key)**: Returns specific order by ID. +- **Post()**: Creates new order; `Created()` returns 201 status with new record. +- **Patch()**: Updates existing order; only changes specified fields. +- **Delete()**: Removes order; `NoContent()` returns 204 status. + +### Custom URLs for CRUD operations + +By default, `ODataV4Adaptor` uses standard OData conventions: +- Create: `POST /odata/Orders`. +- Update: `PATCH /odata/Orders(10001)`. +- Delete: `DELETE /odata/Orders(10001)`. + +Custom URLs become necessary in these scenarios: +- Existing non-OData endpoints cannot be modified. +- CRUD operations must route to different controllers. +- Custom business logic requires special routing. +- Third-party API integration is required. + +**Custom URL implementation:** + +Explicitly specify which URL `SfDataManager` uses for each operation instead of relying on OData routing conventions. + +**Configuring custom URLs:** + +`DataManager` supports these custom URL properties: + +| Property | Purpose | Default Behavior | +|----------|---------|------------------| +| `url` | Read (GET) operations. | `/odata/Orders` | +| `insertUrl` | Create (POST) operations. | Uses `url`. | +| `updateUrl` | Update (PATCH/PUT) operations. | Uses `url/{key}`. | +| `removeUrl` | Delete (DELETE) operations. | Uses `url/{key}`. | +| `batchUrl` | Batch operations. | Uses `url/$batch`. | + +### Separate URLs for each operation + +Use this approach when different API endpoints are assigned to handle specific CRUD or data operations. + +{% tabs %} +{% highlight razor tabtitle="Index.razor" %} + +@using Syncfusion.Blazor.Grids +@using Syncfusion.Blazor.Data +@using ODataV4Adaptor.Client.Models + + + + + + + + + + + + +{% endhighlight %} +{% endtabs %} + +> Ensure the backend defines routes that correspond to these custom URLs. + +## Troubleshooting + +| Issue | Resolution | +|---------------------|-------------------------------------------------------------------------------------------------------| +| **Empty Grid** | Ensure the API returns data, verify "GetAllRecords()" provides results, and check the browser console. | +| **CRUD Not Working**| Confirm the primary key is configured and the controller supports `POST`, `PATCH`, and `DELETE` methods. | +| **Styles Missing** | Verify that Syncfusion CSS files are correctly referenced and fix any missing file errors in console. | + +## Complete sample repository + +For the complete working implementation of this example, refer to the [GitHub location](https://github.com/SyncfusionExamples/Binding-data-from-remote-service-to-blazor-data-grid/tree/master/ODataV4Adaptor). \ No newline at end of file diff --git a/blazor/datagrid/connecting-to-adaptors/url-adaptor.md b/blazor/datagrid/connecting-to-adaptors/url-adaptor.md index 831f2434a9..339818191a 100644 --- a/blazor/datagrid/connecting-to-adaptors/url-adaptor.md +++ b/blazor/datagrid/connecting-to-adaptors/url-adaptor.md @@ -1,6 +1,6 @@ --- layout: post -title: Bind data and perform CRUD action with UrlAdaptor in Syncfusion Blazor DataGrid +title: Blazor DataGrid with UrlAdaptor| Syncfusion description: Learn about bind data and performing CRUD operations using UrlAdaptor in Syncfusion Blazor DataGrid. platform: Blazor control: DataGrid @@ -8,177 +8,52 @@ keywords: adaptors, urladaptor, url adaptor, remotedata documentation: ug --- -# UrlAdaptor in Syncfusion® Blazor DataGrid +# Custom REST API Remote Data Binding in Syncfusion Blazor Components -The [UrlAdaptor](https://blazor.syncfusion.com/documentation/data/adaptors#url-adaptor) serves as the base adaptor for facilitating communication between remote data services and a UI component. It enables seamless data binding and interaction with custom API services or any remote service through URLs. The `UrlAdaptor` is particularly useful in scenarios where a custom API service with unique logic for handling data and CRUD operations is in place. This approach allows for custom handling of data, with the resultant data returned in the `result` and `count` format for display in the Syncfusion® Blazor DataGrid. +The [UrlAdaptor](https://blazor.syncfusion.com/documentation/data/adaptors) in the Syncfusion® Blazor DataManager streamlines connecting the Blazor DataGrid to REST API endpoints by managing request and response handling for remote data operations. It automatically converts DataGrid actions such as filtering, sorting, paging, and CRUD into HTTP POST requests and processes the server’s JSON response, enabling smooth remote data binding without custom request logic. -This section describes a step-by-step process for retrieving data using the `UrlAdaptor` and binding it to the Blazor DataGrid to facilitate data and CRUD operations. +For details on configuring the backend (expected request/response format, server‑side processing), refer to the [UrlAdaptor backend setup documentation](https://blazor.syncfusion.com/documentation/data/adaptors). -## Creating an API Service - -To configure a server with the Syncfusion® Blazor DataGrid, follow these steps: - -**1. Create a Blazor web app** - -You can create a **Blazor Web App** named **URLAdaptor** using Visual Studio 2022, either via [Microsoft Templates](https://learn.microsoft.com/en-us/aspnet/core/blazor/tooling?view=aspnetcore-8.0) or the [Syncfusion® Blazor Extension](https://blazor.syncfusion.com/documentation/visual-studio-integration/template-studio). Make sure to configure the appropriate [interactive render mode](https://learn.microsoft.com/en-us/aspnet/core/blazor/components/render-modes?view=aspnetcore-8.0#render-modes) and [interactivity location](https://learn.microsoft.com/en-us/aspnet/core/blazor/tooling?view=aspnetcore-8.0&pivots=windows). +Once the project creation and backend setup are complete, the next step is to integrate the Syncfusion® Blazor DataGrid with `UrlAdaptor`. -**2. Create a model class** - -Create a new folder named **Models**. Then, add a model class named **OrdersDetails.cs** in the **Models** folder to represent the order data. - -```csharp -namespace URLAdaptor.Models -{ - public class OrdersDetails - { - public static List order = new List(); +## Integrating Syncfusion Blazor DataGrid with UrlAdaptor - public OrdersDetails() { } - - public OrdersDetails(int OrderID, string CustomerId, int EmployeeId, double Freight, bool Verified, DateTime OrderDate, string ShipCity, string ShipName, string ShipCountry, DateTime ShippedDate, string ShipAddress) - { - this.OrderID = OrderID; - this.CustomerID = CustomerId; - this.EmployeeID = EmployeeId; - this.Freight = Freight; - this.ShipCity = ShipCity; - this.Verified = Verified; - this.OrderDate = OrderDate; - this.ShipName = ShipName; - this.ShipCountry = ShipCountry; - this.ShippedDate = ShippedDate; - this.ShipAddress = ShipAddress; - } +### Step 1: Install and Configure Blazor DataGrid Components - public static List GetAllRecords() - { - if (order.Count() == 0) - { - int code = 10000; - for (int i = 1; i < 10; i++) - { - order.Add(new OrdersDetails(code + 1, "ALFKI", i + 0, 2.3 * i, false, new DateTime(1991, 05, 15), "Berlin", "Simons bistro", "Denmark", new DateTime(1996, 7, 16), "Kirchgasse 6")); - order.Add(new OrdersDetails(code + 2, "ANATR", i + 2, 3.3 * i, true, new DateTime(1990, 04, 04), "Madrid", "Queen Cozinha", "Brazil", new DateTime(1996, 9, 11), "Avda. Azteca 123")); - order.Add(new OrdersDetails(code + 3, "ANTON", i + 1, 4.3 * i, true, new DateTime(1957, 11, 30), "Cholchester", "Frankenversand", "Germany", new DateTime(1996, 10, 7), "Carrera 52 con Ave. Bolívar #65-98 Llano Largo")); - order.Add(new OrdersDetails(code + 4, "BLONP", i + 3, 5.3 * i, false, new DateTime(1930, 10, 22), "Marseille", "Ernst Handel", "Austria", new DateTime(1996, 12, 30), "Magazinweg 7")); - order.Add(new OrdersDetails(code + 5, "BOLID", i + 4, 6.3 * i, true, new DateTime(1953, 02, 18), "Tsawassen", "Hanari Carnes", "Switzerland", new DateTime(1997, 12, 3), "1029 - 12th Ave. S.")); - code += 5; - } - } - return order; - } - - public int? OrderID { get; set; } - public string? CustomerID { get; set; } - public int? EmployeeID { get; set; } - public double? Freight { get; set; } - public string? ShipCity { get; set; } - public bool? Verified { get; set; } - public DateTime OrderDate { get; set; } - public string? ShipName { get; set; } - public string? ShipCountry { get; set; } - public DateTime ShippedDate { get; set; } - public string? ShipAddress { get; set; } - } -} -``` - -**3. Create an API controller** - -Create an API controller (aka, **GridController.cs**) file under **Controllers** folder that helps to establish data communication with the Blazor DataGrid. - -```csharp - -using Microsoft.AspNetCore.Mvc; -using Syncfusion.Blazor.Data; -using Syncfusion.Blazor; -using URLAdaptor.Models; - -namespace URLAdaptor.Controllers -{ - [ApiController] - public class GridController : ControllerBase - { - /// - /// Retrieves the list of orders. - /// - /// Retrieve data from the data source. - [HttpGet] - public List GetOrderData() - { - return OrdersDetails.GetAllRecords().ToList(); - } - - /// - /// Handles server-side data operations such as filtering, sorting, paging, and returns the processed data. - /// - /// Returns the data and total count in result and count format. - [HttpPost] - [Route("api/[controller]")] - public object Post() - { - // Retrieve data source and convert to queryable. - IQueryable DataSource = GetOrderData().AsQueryable(); - - // Get total records count. - int totalRecordsCount = DataSource.Count(); - - // Return data and count. - return new { result = DataSource, count = totalRecordsCount }; - } - } -} - -``` - -> The **GetOrderData** method retrieves sample order data. Replace it with your custom logic to fetch data from a database or other sources. +Syncfusion is a library that provides pre-built UI components like DataGrid, which is used to display data in a table format. -**4. Register controllers in `Program.cs`** - -Add the following lines in the `Program.cs` file to register controllers: - -```csharp -// Register controllers in the service container. -builder.Services.AddControllers(); - -// Map controller routes. -app.MapControllers(); -``` - -**5. Run the application** - -Run the application in Visual Studio. The API will be accessible at a URL like **https://localhost:xxxx/api/grid** (where **xxxx** represents the port number). Please verify that the API returns the order data. - -![UrlAdaptor Data](../images/blazor-datagrid-adaptors-data.png) +**Instructions:** -## Connecting Syncfusion® Blazor DataGrid to an API service - -To integrate the Syncfusion® Blazor DataGrid into your project using Visual Studio, follow the below steps: - **1. Install Syncfusion® Blazor DataGrid and Themes NuGet packages** - -To add the Blazor DataGrid in the app, open the NuGet Package Manager in Visual Studio (*Tools → NuGet Package Manager → Manage NuGet Packages for Solution*), search and install [Syncfusion.Blazor.Grid](https://www.nuget.org/packages/Syncfusion.Blazor.Grid/) and [Syncfusion.Blazor.Themes](https://www.nuget.org/packages/Syncfusion.Blazor.Themes/). - -If your Blazor Web App uses `WebAssembly` or `Auto` render modes, install the Syncfusion® Blazor NuGet packages in the client project. - -Alternatively, use the following Package Manager commands: - + +**Method 1: Using Package Manager Console** + +1. Open Visual Studio 2026. +2. Navigate to Tools → NuGet Package Manager → Package Manager Console. +3. Run the following commands: + ```powershell -Install-Package Syncfusion.Blazor.Grid -Version {{ site.releaseversion }} -Install-Package Syncfusion.Blazor.Themes -Version {{ site.releaseversion }} +Install-Package Syncfusion.Blazor.Grid -Version {{site.blazorversion}}; +Install-Package Syncfusion.Blazor.Themes -Version {{site.blazorversion}}; ``` - -> Syncfusion® Blazor components are available on [nuget.org](https://www.nuget.org/packages?q=syncfusion.blazor). Refer to the [NuGet packages](https://blazor.syncfusion.com/documentation/nuget-packages) topic for a complete list of available packages. - + +**Method 2: Using NuGet Package Manager UI** + +1. Open Visual Studio 2026 → Tools → NuGet Package Manager → Manage NuGet Packages for Solution. +2. Search for and install each package individually: + - **[Syncfusion.Blazor.Grid](https://www.nuget.org/packages/Syncfusion.Blazor.Grid/)** (version {{site.blazorversion}}) + - **[Syncfusion.Blazor.Themes](https://www.nuget.org/packages/Syncfusion.Blazor.Themes/)** (version {{site.blazorversion}}) + +All required packages are now installed. + **2. Register Syncfusion® Blazor service** - -- Open the **~/_Imports.razor** file and import the required namespaces. - -```cs + +Import the required namespaces in the `Components/_Imports.razor` file: + +```csharp @using Syncfusion.Blazor @using Syncfusion.Blazor.Grids ``` - - Register the Syncfusion® Blazor service in the **~/Program.cs** file. ```csharp @@ -186,54 +61,109 @@ using Syncfusion.Blazor; builder.Services.AddSyncfusionBlazor(); ``` - -For apps using `WebAssembly` or `Auto (Server and WebAssembly)` render modes, register the service in both **~/Program.cs** files. + For apps using `WebAssembly` or `Auto (Server and WebAssembly)` render modes, register the service in both **~/Program.cs** files. **3. Add stylesheet and script resources** - -Include the theme stylesheet and script references in the **~/Components/App.razor** file. - + +Add the Syncfusion stylesheet and scripts in the `Components/App.razor` file. Find the `` section and add: + ```html - - .... - - -.... - - .... - - + + + + + ``` - -> * Refer to the [Blazor Themes](https://blazor.syncfusion.com/documentation/appearance/themes) topic for various methods to include themes (e.g., Static Web Assets, CDN, or CRG). -> * Set the render mode to **InteractiveServer** or **InteractiveAuto** in your Blazor Web App configuration. - -**4. Add Blazor DataGrid and configure with server** - -To connect the Blazor DataGrid to a hosted API, use the [Url](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.DataManager.html#Syncfusion_Blazor_DataManager_Url) property of [SfDataManager](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.DataManager.html). Update the **Index.razor** file as follows. -The `SfDataManager` offers multiple adaptor options to connect with remote database based on an API service. Below is an example of the [UrlAdaptor](https://blazor.syncfusion.com/documentation/data/adaptors#url-adaptor) configuration where an API service are set up to return the resulting data in the result and count format. - -{% tabs %} -{% highlight razor tabtitle="Index.razor" %} +For this project, the **bootstrap5** theme is used. A different theme can be selected or customized based on project requirements. Refer to the [Syncfusion Blazor Components Appearance](https://blazor.syncfusion.com/documentation/appearance/themes) documentation to learn more about theming and customization options. -@using Syncfusion.Blazor.Grids -@using Syncfusion.Blazor.Data -@using URLAdaptor.Models +Syncfusion components are now configured and ready to use. For additional guidance, refer to the DataGrid component's [getting‑started](https://blazor.syncfusion.com/documentation/datagrid/getting-started-with-web-app) documentation. - - +### Step 2: Update the Blazor DataGrid with UrlAdaptor + +DataGrid integration with backend APIs is enabled through the `UrlAdaptor`, which serves as a connector between the Syncfusion Blazor DataManager and RESTful services. It automatically converts DataGrid actions such as paging, sorting, filtering, searching, and grouping into structured HTTP requests that the server can interpret. This design is particularly effective for large datasets where server‑side processing is essential. + +By delegating these operations to the server rather than executing them in the browser, the DataGrid ensures that only the required data is retrieved for each request. + +In the below code example, `Index.razor` will display the order data in a Syncfusion Blazor DataGrid with search, filter, sort, paging, and CRUD capabilities using `UrlAdaptor` to communicate with REST API endpoints. + +**Instructions:** + +1. Open the file named `Index.razor` in the `Components/Pages` folder. +2. Replace the entire content with the following code: + +```cshtml +@page "/" + + + + + + - - - - + + + + + + + + + + + @{ + var aggregate = (context as AggregateTemplateContext); +
+

Sum: @aggregate?.Sum

+
+ } +
+ + @{ + var aggregate = (context as AggregateTemplateContext); +
+

Sum: @aggregate?.Sum

+
+ } +
+
+
+
+
- -{% endhighlight %} - -{% highlight cs tabtitle="GridController.cs" %} + +``` + +**Component Explanation:** + +- **``**: The DataGrid component that displays order data in rows and columns. +- **``**: Manages data communication with REST API endpoints using UrlAdaptor. The `Url` property points to the read endpoint, while `InsertUrl`, `UpdateUrl`, `RemoveUrl`, and `BatchUrl` point to CRUD endpoints. +- **`AllowPaging="true"`**: Enables pagination to display records in pages of 12 records each. +- **`AllowFiltering="true"`**: Enables column filtering. +- **`AllowGrouping="true"`**: Allows grouping by dragging columns to the group area. +- **`AllowSorting="true"`**: Enables column sorting by clicking headers. +- **``**: Defines the columns displayed in the DataGrid, mapped to `Order` model properties. +- **``**: Enables inline editing in `Normal` mode (edit one row at a time). +- **`Toolbar`**: "Add", "Edit", "Delete", "Update", "Cancel", "Search" for CRUD and search operations. +- **``**: Displays summary calculations (Sum, Count, Average, Min, Max) in footer rows. The `` shows aggregates for each group, while `` displays aggregates for the entire DataGrid at the bottom. + +> In **URL Adaptor**, the DataGrid handles grouping and aggregation operations automatically. + +### Step 3: Implement the Endpoints for UrlAdaptor + +The `UrlAdaptor` communicates with REST API endpoints for DataGrid operations rather than executing logic in the component. The DataGrid sends requests to endpoints defined in a controller. Below is the controller structure with the same decorators and signatures as in the project, with placeholder comments to add logic. + +Open the file named **Controllers/GridController.cs** and use the following structure: + +```csharp using Microsoft.AspNetCore.Mvc; using Syncfusion.Blazor.Data; @@ -262,7 +192,7 @@ namespace URLAdaptor.Controllers /// Returns the data and total count in result and count format. [HttpPost] [Route("api/[controller]")] - public object Post() + public object Post([FromBody] DataManagerRequest DataManagerRequest) { // Retrieve data source and convert to queryable. IQueryable DataSource = GetOrderData().AsQueryable(); @@ -273,36 +203,132 @@ namespace URLAdaptor.Controllers // Return data and count. return new { result = DataSource, count = totalRecordsCount }; } + + /// + /// Inserts a new order record. + /// + [HttpPost("Insert")] + [Route("api/[controller]/Insert")] + public void Insert([FromBody] CRUDModel value) + { + // implement logic here. + } + + /// + /// Updates an existing order record. + /// + [HttpPost("Update")] + [Route("api/[controller]/Update")] + public void Update([FromBody] CRUDModel value) + { + // implement logic here. + } + + /// + /// Deletes an order record. + /// + [HttpPost("Delete")] + [Route("api/[controller]/Delete")] + public void Delete([FromBody] CRUDModel value) + { + // implement logic here. + } + + /// + /// Batch operations for Insert, Update, and Delete. + /// + [HttpPost("Batch")] + [Route("api/[controller]/BatchUpdate")] + public void Batch([FromBody] CRUDModel value) + { + // implement logic here. + } + } + + /// + /// CRUD Model for handling data operations. + /// + public class CRUDModel where T : class + { + [JsonPropertyName("action")] + public string? Action { get; set; } + [JsonPropertyName("keyColumn")] + public string? KeyColumn { get; set; } + [JsonPropertyName("key")] + public object? Key { get; set; } + [JsonPropertyName("value")] + public T? Value { get; set; } + [JsonPropertyName("added")] + public List? Added { get; set; } + [JsonPropertyName("changed")] + public List? Changed { get; set; } + [JsonPropertyName("deleted")] + public List? Deleted { get; set; } + [JsonPropertyName("params")] + public IDictionary? Params { get; set; } } } -{% endhighlight %} -{% endtabs %} - -> Replace https://localhost:xxxx/api/grid with the actual URL of your API endpoint that provides the data in a consumable format (e.g., JSON). - -**5. Run the application** +``` -When you run the application, the Blazor DataGrid will display data fetched from the API. +> Replace https://localhost:xxxx/api/Grid with the actual URL of your API endpoint that provides the data in a consumable format (e.g., JSON). + +The `CRUDModel` is the payload contract used by `UrlAdaptor` for insert, update, delete, and batch requests. +It carries the primary key, single entity (Value), and collections (Added, Changed, Deleted) for batch operations. + +This controller exposes the endpoints used by `` in **Home.razor**. Logic will be added in later steps when wiring CRUD and batch operations. + +### Step 4: Running the Application + +**Build the Application** + +1. Open PowerShell or your terminal. +2. Navigate to the project directory. +3. Build the application: + +```powershell +dotnet build +``` + +**Run the Application** + +Execute the following command: + +```powershell +dotnet run +``` + +The application will start, and the console will display the local URL (typically `http://localhost:5175` or `https://localhost:5001`). + +**Access the Application** + +1. Open a web browser. +2. Navigate to the URL displayed in the console. +3. The DataGrid application is now running and ready to use. ![UrlAdaptor Data](../images/blazor-datagrid-adaptors.gif) - + +## Server-side data operations + > * The Syncfusion® Blazor DataGrid supports server-side operations such as **searching**, **sorting**, **filtering**, **aggregating**, and **paging**. These can be handled using methods like [PerformSearching](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.DataOperations.html#Syncfusion_Blazor_DataOperations_PerformSearching__1_System_Linq_IQueryable___0__System_Collections_Generic_List_Syncfusion_Blazor_Data_SearchFilter__), [PerformFiltering](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.DataOperations.html#Syncfusion_Blazor_DataOperations_PerformFiltering__1_System_Linq_IQueryable___0__System_Collections_Generic_List_Syncfusion_Blazor_Data_WhereFilter__System_String_), [PerformSorting](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.DataOperations.html#Syncfusion_Blazor_DataOperations_PerformSorting__1_System_Linq_IQueryable___0__System_Collections_Generic_List_Syncfusion_Blazor_Data_Sort__), [PerformTake](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.DataOperations.html#Syncfusion_Blazor_DataOperations_PerformTake__1_System_Linq_IQueryable___0__System_Int32_), and [PerformSkip](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.DataOperations.html#Syncfusion_Blazor_DataOperations_PerformSkip__1_System_Linq_IQueryable___0__System_Int32_) from the **Syncfusion.Blazor.Data** package. Let's explore how to manage these data operations using the `UrlAdaptor`. > * In an API service project, add **Syncfusion.Blazor.Data** by opening the NuGet package manager in Visual Studio (Tools → NuGet Package Manager → Manage NuGet Packages for Solution), search and install it. -## Handling searching operation +### Implement Paging Feature -To handle the searching operation, ensure that your API endpoint supports custom searching criteria. Implement the searching logic on the server side using the [PerformSearching](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.DataOperations.html#Syncfusion_Blazor_DataOperations_PerformSearching__1_System_Linq_IQueryable___0__System_Collections_Generic_List_Syncfusion_Blazor_Data_SearchFilter__) method from the [DataOperations](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.DataOperations.html) class. This allows the custom data source to undergo searching based on the criteria specified in the incoming [DataManagerRequest](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.DataManagerRequest.html) object. +Paging divides large datasets into smaller pages to improve performance and usability. -![UrlAdaptor - Searching](../images/urladaptor-searching.png) +**Instructions:** + +* Ensure the DataGrid has paging enabled with `AllowPaging="true"`. +* Implement the `Post` action in **Controllers/GridController.cs** to apply only paging using the [PerformTake](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.DataOperations.html#Syncfusion_Blazor_DataOperations_PerformTake__1_System_Linq_IQueryable___0__System_Int32_) and [PerformSkip](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.DataOperations.html#Syncfusion_Blazor_DataOperations_PerformSkip__1_System_Linq_IQueryable___0__System_Int32_) methods from the [DataOperations](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.DataOperations.html) class. This allows the custom data source to undergo paging based on the criteria specified in the incoming [DataManagerRequest](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.DataManagerRequest.html) object. {% tabs %} {% highlight cs tabtitle="GridController.cs" %} /// -/// Handles server-side data operations such as searching and returns the processed data. +/// Handles server-side data operations such as paging and returns the processed data. /// -/// The request object contains searched details. +/// The request object contains pagination details. /// Returns a response containing the processed data and the total record count. [HttpPost] [Route("api/[controller]")] @@ -311,15 +337,20 @@ public object Post([FromBody] DataManagerRequest DataManagerRequest) // Retrieve data from the data source. IQueryable DataSource = GetOrderData().AsQueryable(); - // Handling searching operation. - if (DataManagerRequest.Search != null && DataManagerRequest.Search.Count > 0) + // Get the total records count. + int totalRecordsCount = DataSource.Count(); + + // Handling paging operation. + if (DataManagerRequest.Skip != 0) { - DataSource = DataOperations.PerformSearching(DataSource, DataManagerRequest.Search); + DataSource = DataOperations.PerformSkip(DataSource, DataManagerRequest.Skip); + // Add custom logic here if needed and remove above method. + } + if (DataManagerRequest.Take != 0) + { + DataSource = DataOperations.PerformTake(DataSource, DataManagerRequest.Take); // Add custom logic here if needed and remove above method. } - - // Get the total records count. - int totalRecordsCount = DataSource.Count(); // Return data based on the request. return new { result = DataSource, count = totalRecordsCount }; @@ -333,8 +364,8 @@ public object Post([FromBody] DataManagerRequest DataManagerRequest) @using Syncfusion.Blazor.Data @using URLAdaptor.Models - - + + @@ -346,9 +377,19 @@ public object Post([FromBody] DataManagerRequest DataManagerRequest) {% endhighlight %} {% endtabs %} -### Handling filtering operation +**How Paging Works:** +- The DataGrid posts `Skip` and `Take` to `http://localhost:5175/api/Grid`. +- The controller returns the paged `result` and total `count` for correct pager UI. + +### Implement Filtering Feature + +Filtering allows the user to restrict data based on column values. + +**Instructions:** -To handle the filtering operation, ensure that your API endpoint supports custom filtering criteria. Implement the filtering logic on the server side using the [PerformFiltering](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.DataOperations.html#Syncfusion_Blazor_DataOperations_PerformFiltering__1_System_Linq_IQueryable___0__System_Collections_Generic_List_Syncfusion_Blazor_Data_WhereFilter__System_String_) method from the [DataOperations](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.DataOperations.html) class. This allows the custom data source to undergo filtering based on the criteria specified in the incoming [DataManagerRequest](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.DataManagerRequest.html) object. +* Open the `Components/Pages/Home.razor` file. +* Add the [AllowFiltering](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Grids.SfGrid-1.html#Syncfusion_Blazor_Grids_SfGrid_1_AllowFiltering) property to the ``. +* Implement the `Post` action in **Controllers/GridController.cs** to handle filtering using the [PerformFiltering](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.DataOperations.html#Syncfusion_Blazor_DataOperations_PerformFiltering__1_System_Linq_IQueryable___0__System_Collections_Generic_List_Syncfusion_Blazor_Data_WhereFilter__System_String_) method from the [DataOperations](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.DataOperations.html) class. This allows the custom data source to undergo filtering based on the criteria specified in the incoming [DataManagerRequest](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.DataManagerRequest.html) object. **Single column filtering** ![Single column filtering](../images/urladaptor-filtering.png) @@ -400,7 +441,7 @@ public object Post([FromBody] DataManagerRequest DataManagerRequest) @using URLAdaptor.Models - + @@ -412,23 +453,31 @@ public object Post([FromBody] DataManagerRequest DataManagerRequest) {% endhighlight %} {% endtabs %} -## Handling sorting operation +**How Filtering Works:** -To handle the sorting operation, ensure that your API endpoint supports custom sorting criteria. Implement the sorting logic on the server side using the [PerformSorting](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.DataOperations.html#Syncfusion_Blazor_DataOperations_PerformSorting__1_System_Linq_IQueryable___0__System_Collections_Generic_List_Syncfusion_Blazor_Data_Sort__) method from the [DataOperations](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.DataOperations.html) class. This allows the custom data source to undergo sorting based on the criteria specified in the incoming [DataManagerRequest](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.DataManagerRequest.html) object. +- When the user enters text in the filter bar and presses Enter, the DataGrid sends a request to the REST API. +- The `Post` method receives the filter criteria in `dataManagerRequest.Where`. +- The `DataOperations.PerformFiltering()` method applies the filter conditions to the data. +- Results are filtered accordingly and displayed in the DataGrid. -**Single column sorting** -![Single column sorting](../images/urladaptor-sorting.png) +### Implement Searching Feature -**Multi column sorting** -![Multi column sorting](../images/urladaptor-multi-sorting.png) +Searching allows the user to find records by entering keywords in the search box, which filters data across all columns. + +**Instructions:** + +* Ensure the toolbar includes the "Search" item. +* Implement the `Post` action in **Controllers/GridController.cs** to handle searching using the [PerformSearching](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.DataOperations.html#Syncfusion_Blazor_DataOperations_PerformSearching__1_System_Linq_IQueryable___0__System_Collections_Generic_List_Syncfusion_Blazor_Data_SearchFilter__) method from the [DataOperations](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.DataOperations.html) class. This allows the custom data source to undergo searching based on the criteria specified in the incoming [DataManagerRequest](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.DataManagerRequest.html) object. + +![UrlAdaptor - Searching](../images/urladaptor-searching.png) {% tabs %} {% highlight cs tabtitle="GridController.cs" %} /// -/// Handles server-side data operations such as sorting and returns the processed data. +/// Handles server-side data operations such as searching and returns the processed data. /// -/// The request object contains sorted details. +/// The request object contains searched details. /// Returns a response containing the processed data and the total record count. [HttpPost] [Route("api/[controller]")] @@ -437,14 +486,14 @@ public object Post([FromBody] DataManagerRequest DataManagerRequest) // Retrieve data from the data source. IQueryable DataSource = GetOrderData().AsQueryable(); - // Handling sorting operation. - if (DataManagerRequest.Sorted != null && DataManagerRequest.Sorted.Count > 0) + // Handling searching operation. + if (DataManagerRequest.Search != null && DataManagerRequest.Search.Count > 0) { - DataSource = DataOperations.PerformSorting(DataSource, DataManagerRequest.Sorted); + DataSource = DataOperations.PerformSearching(DataSource, DataManagerRequest.Search); // Add custom logic here if needed and remove above method. } - // Get the total count of records. + // Get the total records count. int totalRecordsCount = DataSource.Count(); // Return data based on the request. @@ -459,8 +508,8 @@ public object Post([FromBody] DataManagerRequest DataManagerRequest) @using Syncfusion.Blazor.Data @using URLAdaptor.Models - - + + @@ -472,19 +521,36 @@ public object Post([FromBody] DataManagerRequest DataManagerRequest) {% endhighlight %} {% endtabs %} -## Handling paging operation +**How Searching Works:** + +- When the user enters text in the search box and presses Enter, the DataGrid sends a search request to the REST API. +- The `Post` method receives the search criteria in `dataManagerRequest.Search`. +- The `DataOperations.PerformSearching()` method filters the data based on the search term across all columns. +- Results are returned and displayed in the DataGrid with pagination applied. -To handle the paging operation, ensure that your API endpoint supports custom paging criteria. Implement the paging logic on the server side using the [PerformTake](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.DataOperations.html#Syncfusion_Blazor_DataOperations_PerformTake__1_System_Linq_IQueryable___0__System_Int32_) and [PerformSkip](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.DataOperations.html#Syncfusion_Blazor_DataOperations_PerformSkip__1_System_Linq_IQueryable___0__System_Int32_) methods from the [DataOperations](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.DataOperations.html) class. This allows the custom data source to undergo paging based on the criteria specified in the incoming [DataManagerRequest](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.DataManagerRequest.html) object. +### Step 8: Implement Sorting Feature -![UrlAdaptor - Paging](../images/urladaptor-paging.png) +Sorting enables the user to arrange records in ascending or descending order based on column values. + +**Instructions:** + +* Open the `Components/Pages/Home.razor` file. +* Add the [AllowSorting](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Grids.SfGrid-1.html#Syncfusion_Blazor_Grids_SfGrid_1_AllowSorting) property to the ``. +* Update the `Post` action in **Controllers/GridController.cs** to handle sorting using the [PerformSorting](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.DataOperations.html#Syncfusion_Blazor_DataOperations_PerformSorting__1_System_Linq_IQueryable___0__System_Collections_Generic_List_Syncfusion_Blazor_Data_Sort__) method from the [DataOperations](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.DataOperations.html) class. This allows the custom data source to undergo sorting based on the criteria specified in the incoming [DataManagerRequest](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.DataManagerRequest.html) object. + +**Single column sorting** +![Single column sorting](../images/urladaptor-sorting.png) + +**Multi column sorting** +![Multi column sorting](../images/urladaptor-multi-sorting.png) {% tabs %} {% highlight cs tabtitle="GridController.cs" %} /// -/// Handles server-side data operations such as paging and returns the processed data. +/// Handles server-side data operations such as sorting and returns the processed data. /// -/// The request object contains pagination details. +/// The request object contains sorted details. /// Returns a response containing the processed data and the total record count. [HttpPost] [Route("api/[controller]")] @@ -493,21 +559,16 @@ public object Post([FromBody] DataManagerRequest DataManagerRequest) // Retrieve data from the data source. IQueryable DataSource = GetOrderData().AsQueryable(); - // Get the total records count. - int totalRecordsCount = DataSource.Count(); - - // Handling paging operation. - if (DataManagerRequest.Skip != 0) - { - DataSource = DataOperations.PerformSkip(DataSource, DataManagerRequest.Skip); - // Add custom logic here if needed and remove above method. - } - if (DataManagerRequest.Take != 0) + // Handling sorting operation. + if (DataManagerRequest.Sorted != null && DataManagerRequest.Sorted.Count > 0) { - DataSource = DataOperations.PerformTake(DataSource, DataManagerRequest.Take); + DataSource = DataOperations.PerformSorting(DataSource, DataManagerRequest.Sorted); // Add custom logic here if needed and remove above method. } + // Get the total count of records. + int totalRecordsCount = DataSource.Count(); + // Return data based on the request. return new { result = DataSource, count = totalRecordsCount }; } @@ -520,8 +581,8 @@ public object Post([FromBody] DataManagerRequest DataManagerRequest) @using Syncfusion.Blazor.Data @using URLAdaptor.Models - - + + @@ -533,21 +594,33 @@ public object Post([FromBody] DataManagerRequest DataManagerRequest) {% endhighlight %} {% endtabs %} -## Handling CRUD operations +**How Sorting Works:** + +- Click on the column header to sort in ascending order. +- Click again to sort in descending order. +- The `Post` method receives the sort criteria in `dataManagerRequest.Sorted`. +- The `DataOperations.PerformSorting()` method sorts the data based on the specified column and direction. +- Records are sorted accordingly and displayed in the DataGrid. + +### Perform CRUD Operations + +The Syncfusion® Blazor DataGrid seamlessly integrates CRUD (Create, Read, Update, and Delete) operations with server-side controller actions through specific properties: [InsertUrl](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.DataManager.html#Syncfusion_Blazor_DataManager_InsertUrl), [RemoveUrl](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.DataManager.html#Syncfusion_Blazor_DataManager_RemoveUrl), [UpdateUrl](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.DataManager.html#Syncfusion_Blazor_DataManager_UpdateUrl), [CrudUrl](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.DataManager.html#Syncfusion_Blazor_DataManager_CrudUrl), and [BatchUrl](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.DataManager.html#Syncfusion_Blazor_DataManager_BatchUrl). These properties enable the DataGrid to communicate with the data service for every DataGrid action, facilitating server-side operations. + +**Instructions:** -The Syncfusion® Blazor DataGrid seamlessly integrates CRUD (Create, Read, Update, and Delete) operations with server-side controller actions through specific properties: [InsertUrl](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.DataManager.html#Syncfusion_Blazor_DataManager_InsertUrl), [RemoveUrl](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.DataManager.html#Syncfusion_Blazor_DataManager_RemoveUrl), [UpdateUrl](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.DataManager.html#Syncfusion_Blazor_DataManager_UpdateUrl), [CrudUrl](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.DataManager.html#Syncfusion_Blazor_DataManager_CrudUrl), and [BatchUrl](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.DataManager.html#Syncfusion_Blazor_DataManager_BatchUrl). These properties enable the Grid to communicate with the data service for every Grid action, facilitating server-side operations. +1. Update the `` in `Home.razor` to include [GridEditSettings](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Grids.GridEditSettings.html): -**CRUD Operations Mapping** +2. **CRUD Operations Mapping** -CRUD operations within the Grid can be mapped to server-side controller actions using specific properties: +CRUD operations within the DataGrid can be mapped to server-side controller actions using specific properties: 1. **InsertUrl**: Specifies the URL for inserting new data. 2. **RemoveUrl**: Specifies the URL for removing existing data. 3. **UpdateUrl**: Specifies the URL for updating existing data. -4. **CrudUrl**: Specifies a single URL for all CRUD operations. -5. **BatchUrl**: Specifies the URL for batch editing. +4. **CrudUrl**: Specifies a single URL for all CRUD operations(alternative to individual URLs). +5. **BatchUrl**: Specifies the URL for batch editing(multiple changes in one request). -To enable editing in Blazor DataGrid, refer to the editing [documentation](https://blazor.syncfusion.com/documentation/datagrid/editing). In the example below, the inline edit [Mode](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Grids.GridEditSettings.html#Syncfusion_Blazor_Grids_GridEditSettings_Mode) is enabled, and the [Toolbar](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Grids.SfGrid-1.html#Syncfusion_Blazor_Grids_SfGrid_1_Toolbar) property is configured to display toolbar items for editing purposes. +For detailed Editing setup, refer to the [Editing documentation](https://blazor.syncfusion.com/documentation/datagrid/editing). {% tabs %} {% highlight razor tabtitle="Index.razor" %} @@ -557,20 +630,18 @@ To enable editing in Blazor DataGrid, refer to the editing [documentation](https @using URLAdaptor.Models - + - - - + // Add Columns. {% endhighlight %} {% endtabs %} -> Normal/Inline editing is the default edit [Mode](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Grids.GridEditSettings.html#Syncfusion_Blazor_Grids_GridEditSettings_Mode) for the Grid. To enable CRUD operations, ensure that the [IsPrimaryKey](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Grids.GridColumn.html#Syncfusion_Blazor_Grids_GridColumn_IsPrimaryKey) property is set to **true** for a specific Grid column, ensuring that its value is unique. +> Normal/Inline editing is the default edit [Mode](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Grids.GridEditSettings.html#Syncfusion_Blazor_Grids_GridEditSettings_Mode) for the DataGrid. To enable CRUD operations, ensure that the [IsPrimaryKey](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Grids.GridColumn.html#Syncfusion_Blazor_Grids_GridColumn_IsPrimaryKey) property is set to **true** for a specific DataGrid column, ensuring that its value is unique. The below class is used to structure data sent during CRUD operations. @@ -588,7 +659,7 @@ public class CRUDModel where T : class } ``` -**Insert operation:** +**Insert (Create)** To insert a new record, use the [InsertUrl](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.DataManager.html#Syncfusion_Blazor_DataManager_InsertUrl) property to specify the controller action mapping URL for the insert operation. The details of the newly added record are passed to the **newRecord** parameter. @@ -616,7 +687,15 @@ public void Insert([FromBody] CRUDModel newRecord) {% endhighlight %} {% endtabs %} -**Update operation:** +**What happens behind the scenes:** + +1. The user clicks the "Add" button and fills in the form. +2. The DataGrid sends a POST request to `http://localhost:5175/api/Grid/Insert`. +3. The `Insert` method receives the new order data in `newRecord.value`and +add the new record to the data collection. +4. The DataGrid automatically refreshes to display the new order. + +**Update (Edit)** For updating existing records, use the [UpdateUrl](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.DataManager.html#Syncfusion_Blazor_DataManager_UpdateUrl) property to specify the controller action mapping URL for the update operation. The details of the updated record are passed to the **updatedRecord** parameter. @@ -653,7 +732,15 @@ public void Update([FromBody] CRUDModel updatedRecord) {% endhighlight %} {% endtabs %} -**Delete operation:** +**What happens behind the scenes:** + +1. The user clicks the "Edit" button and modifies the record. +2. The DataGrid sends a POST request to `http://localhost:5175/api/Grid/Update`. +3. The `Update` method receives the modified order data in `updatedRecord.value`. +4. The existing order is retrieved from the database by its ID. +5. The DataGrid refreshes to display the updated order. + +**Delete (Remove)** To delete existing records, use the [RemoveUrl](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.DataManager.html#Syncfusion_Blazor_DataManager_RemoveUrl) property to specify the controller action mapping URL for the delete operation. The primary key value of the deleted record is passed to the **deletedRecord** parameter. @@ -684,6 +771,14 @@ public void Remove([FromBody] CRUDModel deletedRecord) {% endhighlight %} {% endtabs %} +**What happens behind the scenes:** + +1. The user selects an order and clicks "Delete". +2. A confirmation dialog appears (built into the DataGrid). +3. If confirmed, the DataGrid sends a POST request to `http://localhost:5175/api/Grid/Delete`. +4. The `Delete` method extracts the order ID from `deletedRecord.Key` and remove the record from the data collection. +5. The DataGrid refreshes to remove the deleted order from the UI. + ![UrlAdaptor CRUD operations](../images/adaptor-crud-operation.gif) **Single method for performing all CRUD operations:** @@ -742,7 +837,7 @@ public void CrudUpdate([FromBody] CRUDModel request) @using URLAdaptor.Models - + @@ -757,7 +852,9 @@ public void CrudUpdate([FromBody] CRUDModel request) **Batch operation:** -To perform batch operation, define the edit [Mode](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Grids.GridEditSettings.html#Syncfusion_Blazor_Grids_GridEditSettings_Mode) as **Batch** and specify the [BatchUrl](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.DataManager.html#Syncfusion_Blazor_DataManager_BatchUrl) property in the `DataManager`. Use the **Add** toolbar button to insert new row in batch editing mode. To edit a cell, double-click the desired cell and update the value as required. To delete a record, simply select the record and press the **Delete** toolbar button. Now, all CRUD operations will be executed in single request. Clicking the **Update** toolbar button will update the newly added, edited, or deleted records from the **OrdersDetails** table using a single API POST request. +Batch operations combine multiple insert, update, and delete actions into a single request, minimizing network overhead and ensuring transactional consistency. + +To perform batch operation, define the edit [Mode](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Grids.GridEditSettings.html#Syncfusion_Blazor_Grids_GridEditSettings_Mode) as **Batch** and specify the [BatchUrl](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.DataManager.html#Syncfusion_Blazor_DataManager_BatchUrl) property in the `SfDataManager`. Use the **Add** toolbar button to insert new row in batch editing mode. To edit a cell, double-click the desired cell and update the value as required. To delete a record, simply select the record and press the **Delete** toolbar button. Now, all CRUD operations will be executed in single request. Clicking the **Update** toolbar button will update the newly added, edited, or deleted records from the **OrdersDetails** table using a single API POST request. {% tabs %} {% highlight cs tabtitle="GridController.cs" %} @@ -829,7 +926,7 @@ public IActionResult BatchUpdate([FromBody] CRUDModel batchModel) @using URLAdaptor.Models - + @@ -844,4 +941,8 @@ public IActionResult BatchUpdate([FromBody] CRUDModel batchModel) ![UrlAdaptor - Batch Editing](../images/urladaptor-batch-editing.gif) -Please find the sample in this [GitHub location](https://github.com/SyncfusionExamples/Binding-data-from-remote-service-to-blazor-data-grid/tree/master/UrlAdaptor). \ No newline at end of file +All CRUD operations are now fully implemented, enabling comprehensive data management capabilities within the Blazor DataGrid. + +## Complete Sample Repository + +A complete, working sample implementation is available in the [GitHub repository](ttps://github.com/SyncfusionExamples/Binding-data-from-remote-service-to-blazor-data-grid/tree/master/UrlAdaptor). \ No newline at end of file diff --git a/blazor/datagrid/connecting-to-adaptors/web-api-adaptor.md b/blazor/datagrid/connecting-to-adaptors/web-api-adaptor.md index eb435042ec..795bc57a98 100644 --- a/blazor/datagrid/connecting-to-adaptors/web-api-adaptor.md +++ b/blazor/datagrid/connecting-to-adaptors/web-api-adaptor.md @@ -1,6 +1,6 @@ --- layout: post -title: Bind data and perform CRUD action with WebApiAdaptor in Syncfusion Blazor DataGrid +title: Blazor DataGrid with WebApiAdaptor| Syncfusion description: Learn about bind data and performing CRUD operations using WebApiAdaptor in Syncfusion Blazor DataGrid. platform: Blazor keywords: adaptors, webapiadaptor, webapi adaptor, remotedata @@ -8,177 +8,56 @@ control: DataGrid documentation: ug --- -# WebApiAdaptor in Syncfusion® Blazor DataGrid +# ASP.NET Web API Remote Data Binding in Syncfusion Blazor Components -The [WebApiAdaptor](https://blazor.syncfusion.com/documentation/data/adaptors#web-api-adaptor) is an extension of the [ODataAdaptor](https://blazor.syncfusion.com/documentation/data/adaptors#odata-adaptor), designed to interact with Web APIs created with OData endpoints. This adaptor ensures seamless communication between the Syncfusion® Blazor DataGrid and OData-endpoint-based Web APIs, enabling efficient data retrieval and manipulation. For successful integration, the endpoint must be capable of understanding OData-formatted queries sent along with the request. +The [WebApiAdaptor](https://blazor.syncfusion.com/documentation/data/adaptors#web-api-adaptor) integrates the Blazor DataGrid with Web API endpoints that support OData‑style querying. It is derived from the [ODataAdaptor](https://blazor.syncfusion.com/documentation/data/adaptors#odata-adaptor), meaning the target Web API must accept OData‑formatted query parameters for operations such as filtering, sorting, paging, and searching. When the Syncfusion® Blazor DataGrid performs any data action, the `WebApiAdaptor` generates OData‑compliant query strings, sends them to the Web API endpoint, and processes the returned JSON to populate the DataGrid. This ensures seamless remote data binding with OData-capable Web API services. To enable the OData query option for a Web API, please refer to the corresponding [documentation](https://learn.microsoft.com/en-us/aspnet/web-api/overview/odata-support-in-aspnet-web-api/supporting-odata-query-options), which provides detailed instructions on configuring the endpoint to understand OData-formatted queries. -This section describes a step-by-step process for retrieving data using the `WebApiAdaptor` and binding it to the Blazor Grid to facilitate data and CRUD operations. +For details on configuring the backend (expected request/response format, server‑side processing), refer to the [WebApiAdaptor backend setup documentation](https://blazor.syncfusion.com/documentation/data/adaptors). -## Creating an API service - -To configure a server with the Syncfusion® Blazor DataGrid, follow these steps: - -**1. Create a Blazor web app** - -You can create a **Blazor Web App** named **WebApiAdaptor** using Visual Studio 2022, either via [Microsoft Templates](https://learn.microsoft.com/en-us/aspnet/core/blazor/tooling?view=aspnetcore-8.0) or the [Syncfusion® Blazor Extension](https://blazor.syncfusion.com/documentation/visual-studio-integration/template-studio). Make sure to configure the appropriate [interactive render mode](https://learn.microsoft.com/en-us/aspnet/core/blazor/components/render-modes?view=aspnetcore-8.0#render-modes) and [interactivity location](https://learn.microsoft.com/en-us/aspnet/core/blazor/tooling?view=aspnetcore-8.0&pivots=windows). +Once the project creation and backend setup are complete, the next step is to integrate the Syncfusion® Blazor DataGrid with the `WebApiAdaptor`. -**2. Create a model class** +## Integrating Syncfusion Blazor DataGrid with WebAPIAdaptor -Create a new folder named **Models**. Then, add a model class named **OrdersDetails.cs** in the **Models** folder to represent the order data. +To integrate the Syncfusion® Blazor DataGrid into your project using Visual Studio, follow the below steps: -```csharp -namespace WebApiAdaptor.Models -{ - public class OrdersDetails - { - public static List order = new List(); +### Step 1: Install and Configure Blazor DataGrid Components - public OrdersDetails() { } - - public OrdersDetails(int OrderID, string CustomerId, int EmployeeId, double Freight, bool Verified, DateTime OrderDate, string ShipCity, string ShipName, string ShipCountry, DateTime ShippedDate, string ShipAddress) - { - this.OrderID = OrderID; - this.CustomerID = CustomerId; - this.EmployeeID = EmployeeId; - this.Freight = Freight; - this.ShipCity = ShipCity; - this.Verified = Verified; - this.OrderDate = OrderDate; - this.ShipName = ShipName; - this.ShipCountry = ShipCountry; - this.ShippedDate = ShippedDate; - this.ShipAddress = ShipAddress; - } +Syncfusion is a library that provides pre-built UI components like DataGrid, which is used to display data in a table format. - public static List GetAllRecords() - { - if (order.Count() == 0) - { - int code = 10000; - for (int i = 1; i < 10; i++) - { - order.Add(new OrdersDetails(code + 1, "ALFKI", i + 0, 2.3 * i, false, new DateTime(1991, 05, 15), "Berlin", "Simons bistro", "Denmark", new DateTime(1996, 7, 16), "Kirchgasse 6")); - order.Add(new OrdersDetails(code + 2, "ANATR", i + 2, 3.3 * i, true, new DateTime(1990, 04, 04), "Madrid", "Queen Cozinha", "Brazil", new DateTime(1996, 9, 11), "Avda. Azteca 123")); - order.Add(new OrdersDetails(code + 3, "ANTON", i + 1, 4.3 * i, true, new DateTime(1957, 11, 30), "Cholchester", "Frankenversand", "Germany", new DateTime(1996, 10, 7), "Carrera 52 con Ave. Bolívar #65-98 Llano Largo")); - order.Add(new OrdersDetails(code + 4, "BLONP", i + 3, 5.3 * i, false, new DateTime(1930, 10, 22), "Marseille", "Ernst Handel", "Austria", new DateTime(1996, 12, 30), "Magazinweg 7")); - order.Add(new OrdersDetails(code + 5, "BOLID", i + 4, 6.3 * i, true, new DateTime(1953, 02, 18), "Tsawassen", "Hanari Carnes", "Switzerland", new DateTime(1997, 12, 3), "1029 - 12th Ave. S.")); - code += 5; - } - } - return order; - } +**Instructions:** - public int? OrderID { get; set; } - public string? CustomerID { get; set; } - public int? EmployeeID { get; set; } - public double? Freight { get; set; } - public string? ShipCity { get; set; } - public bool? Verified { get; set; } - public DateTime OrderDate { get; set; } - public string? ShipName { get; set; } - public string? ShipCountry { get; set; } - public DateTime ShippedDate { get; set; } - public string? ShipAddress { get; set; } - } -} -``` -**3. Create an API controller** +**1. Install Syncfusion® Blazor DataGrid and Themes NuGet packages** -Create a new folder named **Controllers**. Then, add a controller named **GridController.cs** in the **Controllers** folder to handle data communication with Blazor DataGrid. Implement the `Get` method in the controller to return data in JSON format, including the `Items` and `Count` properties as required by the `WebApiAdaptor`. +**Method 1: Using Package Manager Console** -The sample response object should look like this: +1. Open Visual Studio 2026. +2. Navigate to Tools → NuGet Package Manager → Package Manager Console. +3. Run the following commands: -``` -{ - Items: [{..}, {..}, {..}, ...], - Count: 830 -} +```powershell +Install-Package Syncfusion.Blazor.Grid -Version {{site.blazorversion}}; +Install-Package Syncfusion.Blazor.Themes -Version {{site.blazorversion}}; ``` -{% tabs %} -{% highlight c# tabtitle="GridController.cs"%} - -using Microsoft.AspNetCore.Mvc; -using Syncfusion.Blazor.Data; -using Syncfusion.Blazor; -using WebApiAdaptor.Models; +**Method 2: Using NuGet Package Manager UI** -namespace WebApiAdaptor.Controllers -{ - [ApiController] - public class GridController : ControllerBase - { - /// - /// Retrieve data from the data source. - /// - /// Returns a JSON object with the list of orders and the total count. - [HttpGet] - [Route("api/[controller]")] - public object GetOrderData() - { - // Retrieve all order records. - List data = OrdersDetails.GetAllRecords().ToList(); +1. Open Visual Studio 2026 → Tools → NuGet Package Manager → Manage NuGet Packages for Solution. +2. Search for and install each package individually: + - **[Syncfusion.Blazor.Grid](https://www.nuget.org/packages/Syncfusion.Blazor.Grid/)** (version {{site.blazorversion}}) + - **[Syncfusion.Blazor.Themes](https://www.nuget.org/packages/Syncfusion.Blazor.Themes/)** (version {{site.blazorversion}}) - // Return the data and total count. - return new { Items = data, Count = data.Count() }; - } - } -} +All required packages are now installed. -{% endhighlight %} -{% endtabs %} +**2. Register Syncfusion® Blazor service** -> When using the WebAPI Adaptor, the data source is returned as a pair of **Items** and **Count**. However, if the `Offline` property of `SfDataManager` is enabled, the entire data source is returned from the server as a collection of objects. In this case, the `$inlinecount` will not be included. Additionally, only a single request is made to fetch all the data from the server, and no further requests are sent. +Import the required namespaces in the `Components/_Imports.razor` file: -**4. Register controllers in `Program.cs`** - -Add the following lines in the `Program.cs` file to register controllers: - ```csharp -// Register controllers in the service container. -builder.Services.AddControllers(); - -// Map controller routes. -app.MapControllers(); -``` - -**5. Run the application** - -Run the application in Visual Studio. The API will be accessible at a URL like **https://localhost:xxxx/api/Grid** (where **xxxx** represents the port number). Please verify that the API returns the order data. - -![WebApiAdaptor Data](../images/web-api-adaptor-data.png) - -## Connecting Syncfusion® Blazor DataGrid to an API service - -To integrate the Syncfusion® Blazor DataGrid into your project using Visual Studio, follow the below steps: - -**1. Install Syncfusion® Blazor DataGrid and Themes NuGet packages** - -To add the Blazor DataGrid in the app, open the NuGet Package Manager in Visual Studio (*Tools → NuGet Package Manager → Manage NuGet Packages for Solution*), search and install [Syncfusion.Blazor.Grid](https://www.nuget.org/packages/Syncfusion.Blazor.Grid/) and [Syncfusion.Blazor.Themes](https://www.nuget.org/packages/Syncfusion.Blazor.Themes/). - -If your Blazor Web App uses `WebAssembly` or `Auto` render modes, install the Syncfusion® Blazor NuGet packages in the client project. - -Alternatively, use the following Package Manager commands: - -```powershell -Install-Package Syncfusion.Blazor.Grid -Version {{ site.releaseversion }} -Install-Package Syncfusion.Blazor.Themes -Version {{ site.releaseversion }} -``` - -> Syncfusion® Blazor components are available on [nuget.org]( https://www.nuget.org/packages?q=syncfusion.blazor). Refer to the [NuGet packages]( https://blazor.syncfusion.com/documentation/nuget-packages) topic for a complete list of available packages. - -**2. Register Syncfusion® Blazor service** - -- Open the **~/_Imports.razor** file and import the required namespaces. - -```cs @using Syncfusion.Blazor @using Syncfusion.Blazor.Grids -@using Syncfusion.Blazor.Data ``` - - Register the Syncfusion® Blazor service in the **~/Program.cs** file. ```csharp @@ -186,34 +65,39 @@ using Syncfusion.Blazor; builder.Services.AddSyncfusionBlazor(); ``` - -For apps using `WebAssembly` or `Auto (Server and WebAssembly)` render modes, register the service in both **~/Program.cs** files. + For apps using `WebAssembly` or `Auto (Server and WebAssembly)` render modes, register the service in both **~/Program.cs** files. **3. Add stylesheet and script resources** - -Include the theme stylesheet and script references in the **~/Components/App.razor** file. - + +Add the Syncfusion stylesheet and scripts in the `Components/App.razor` file. Find the `` section and add: + ```html - - .... - - -.... - - .... - - + + + + + ``` - -> * Refer to the [Blazor Themes](https://blazor.syncfusion.com/documentation/appearance/themes) topic for various methods to include themes (e.g., Static Web Assets, CDN, or CRG). -> * Set the render mode to **InteractiveServer** or **InteractiveAuto** in your Blazor Web App configuration. -**4. Add Blazor DataGrid and configure with server** +For this project, the **bootstrap5** theme is used. A different theme can be selected or customized based on project requirements. Refer to the [Syncfusion Blazor Components Appearance](https://blazor.syncfusion.com/documentation/appearance/themes) documentation to learn more about theming and customization options. + +Syncfusion components are now configured and ready to use. For additional guidance, refer to the Grid component's [getting‑started](https://blazor.syncfusion.com/documentation/datagrid/getting-started-with-web-app) documentation. + +### Step 2: Update the Blazor DataGrid with WebAPIAdaptor -To connect the Blazor DataGrid to a hosted API, use the [Url]( https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.DataManager.html#Syncfusion_Blazor_DataManager_Url) property of [SfDataManager]( https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Data.SfDataManager.html). The `SfDataManager` offers multiple adaptor options to connect with remote database based on an API service. Below is an example of the [WebApiAdaptor](https://blazor.syncfusion.com/documentation/data/adaptors#web-api-adaptor) configuration where an API service are set up to return the resulting data in the **Items** and **Count** format. Update the **Index.razor** file as follows. +Syncfusion® Blazor DataGrid integration with backend APIs is enabled through the `WebApiAdaptor`, which acts as a bridge between the Syncfusion `SfDataManager` and RESTful Web API endpoints. It converts DataGrid actions into OData‑compliant query parameters and is well‑suited for APIs that follow OData conventions, providing server‑side paging, filtering, sorting, and searching without the need for custom request logic. + +By delegating these operations to the server rather than executing them in the browser, the DataGrid ensures that only the required data is retrieved for each request. + +**Instructions:** + +1. To connect the Blazor DataGrid to a hosted API, use the [Url]( https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.DataManager.html#Syncfusion_Blazor_DataManager_Url) property of [SfDataManager]( https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Data.SfDataManager.html). The `SfDataManager` offers multiple adaptor options to connect with remote database based on an API service. Below is an example of the [WebApiAdaptor](https://blazor.syncfusion.com/documentation/data/adaptors#web-api-adaptor) configuration where an API service are set up to return the resulting data in the **Items** and **Count** format. + +2.Update the **Index.razor** file in the `Components/Pages` folder as follows. -{% tabs %} -{% highlight razor tabtitle="Index.razor"%} +```cshtml + +@page "/" @using Syncfusion.Blazor.Grids @using Syncfusion.Blazor.Data @@ -228,10 +112,17 @@ To connect the Blazor DataGrid to a hosted API, use the [Url]( https://help.sync - -{% endhighlight %} - -{% highlight c# tabtitle="GridController.cs"%} + + ``` +> When using the `WebApiAdaptor`, the server must return a JSON response containing both the data collection (`Items`) and the total record count (`Count`) so the Blazor `SfDataManager` can correctly process paging and data binding. + +### Step 3: Implement the Endpoints for WebAPIAdaptor + +The `WebApiAdaptor` communicates with REST API endpoints for DataGrid operations rather than executing logic in the component. The DataGrid sends requests to endpoints defined in a controller. Below is the controller structure with the same decorators and signatures as in the project, with placeholder comments to add logic. + +Open the file named **Controllers/GridController.cs** and use the following structure: + +```csharp using Microsoft.AspNetCore.Mvc; using Syncfusion.Blazor.Data; @@ -259,19 +150,42 @@ namespace WebApiAdaptor.Controllers } } } - -{% endhighlight %} -{% endtabs %} + +``` > Replace https://localhost:xxxx/api/Grid with the actual URL of your API endpoint that provides the data in a consumable format (e.g., JSON). -**5. Run the application** - -When you run the application, the Blazor Grid will display data fetched from the API. +### Step 4: Running the Application + +**Build the Application** + +1. Open PowerShell or your terminal. +2. Navigate to the project directory. +3. Build the application: + +```powershell +dotnet build +``` + +**Run the Application** + +Execute the following command: + +```powershell +dotnet run +``` + +The application will start, and the console will display the local URL (typically `http://localhost:5175` or `https://localhost:5001`). + +**Access the Application** + +1. Open a web browser. +2. Navigate to the URL displayed in the console. +3. The DataGrid application is now running and ready to use. -![WebMethod Adaptor Data](../images/blazor-datagrid-adaptors.gif) +![WebAPI data](../images/blazor-datagrid-adaptors.gif) -**Perform data operations in a WebAPI service** +## Server-side data operations When using the `WebApiAdaptor` with the `SfDataManager`, data operations such as filtering, sorting, paging, and searching are executed on the server side. These operations are sent from the client to the server as **QueryString** parameters, which can be accessed in your API controller using `Request.Query`. @@ -287,21 +201,22 @@ The following table lists the query parameters used by the Blazor DataGrid for v > These parameters are automatically sent when the `WebApiAdaptor` is used. You can access and process them in your Web API Controller to perform the corresponding operations. -## Handling search operations +### Implement Paging Feature -When a search operation is triggered, the `$filter` parameter is sent to the server. The `$filter` parameter specifies the query conditions that are applied to the data to perform the search. +* Ensure the DataGrid has paging enabled with `AllowPaging="true"`. +* When paging is applied, the `$skip` and `$top` parameters are sent to the server. The `$skip` parameter specifies the number of records to skip, while the `$top` parameter specifies how many records to retrieve for the current page. -The following example demonstrates how to extract the `$filter` parameter and apply search logic across multiple fields: +The following example demonstrates how to apply paging logic: -![WebApiAdaptor - Searching](../images/web-api-adaptor-searching.png) +![WebApiAdaptor - Paging](../images/web-api-adaptor-paging.png) {% tabs %} {% highlight cs tabtitle="GridController.cs" %} /// -/// Retrieves order data and handles search operations based on the provided filter query. +/// Retrieves order data and applies paging logic based on the provided query parameters. /// -/// Returns a JSON object containing the searched list of orders and the total count. +/// Returns a JSON object containing the paged list of orders and the total record count. [HttpGet] [Route("api/[controller]")] public object GetOrderData() @@ -312,48 +227,21 @@ public object GetOrderData() // Extract the query string from the incoming request. var queryString = Request.Query; - // Enable nullable reference types for handling filter queries. - #nullable enable - string? filterQuery = queryString["$filter"]; - #nullable disable - - // Check if a filter query is provided. - if (!string.IsNullOrEmpty(filterQuery)) - { - // Split the filter query into individual conditions using "and" as a delimiter. - var filterConditions = filterQuery.Split(new[] { " and " }, StringSplitOptions.RemoveEmptyEntries); - - foreach (var condition in filterConditions) - { - // Check if the condition involves a substring search. - if (condition.Contains("substringof")) - { - // Extract the search value from the substring condition. - var conditionParts = condition.Split('(', ')', '\''); - var searchValue = conditionParts[3]?.ToLower() ?? ""; + // Calculate the total count of records before applying paging. + int totalRecordsCount = data.Count(); - // Filter the data based on the search value across multiple fields. - data = data.Where(order => - order != null && - (order.OrderID.ToString().Contains(searchValue) || - (order.CustomerID?.ToLower().Contains(searchValue, StringComparison.CurrentCultureIgnoreCase) ?? false) || - (order.ShipCity?.ToLower().Contains(searchValue, StringComparison.CurrentCultureIgnoreCase) ?? false) || - (order.ShipCountry?.ToLower().Contains(searchValue, StringComparison.CurrentCultureIgnoreCase) ?? false)) - ).ToList(); - } - else - { - // Handle other filtering operations here. - } - } - } + // Extract the number of records to skip from the query string. + int skip = Convert.ToInt32(queryString["$skip"]); - // Calculate the total count of records. - int totalRecordsCount = data.Count(); + // Extract the number of records to take from the query string. + int take = Convert.ToInt32(queryString["$top"]); - // Return the filtered data and the total count as a JSON object. - return new { Items = data, count = totalRecordsCount }; + // Apply paging by skipping the specified number of records and taking the required number of records. + return take != 0 + ? new { Items = data.Skip(skip).Take(take).ToList(), Count = totalRecordsCount } + : new { Items = data, Count = totalRecordsCount }; } + {% endhighlight %} {% highlight razor tabtitle="Index.razor" %} @@ -362,7 +250,7 @@ public object GetOrderData() @using Syncfusion.Blazor.Data @using Syncfusion.Blazor - + @@ -375,11 +263,12 @@ public object GetOrderData() {% endhighlight %} {% endtabs %} -> This example demonstrates a custom way of handling the `$filter` query sent by the Grid. You can also handle it using your own logic based on the query string format or use dynamic expression evaluation libraries for a more generic approach.. +> Always calculate the total record count before applying paging. This ensures that the DatGrid can display the correct total number of records for pagination. -## Handling filtering operation +### Implement Filtering Feature -When filtering is applied, the `$filter` parameter is sent to the server. The `$filter` parameter specifies the conditions for filtering the data based on the provided criteria. +* Add the [AllowFiltering](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Grids.SfGrid-1.html#Syncfusion_Blazor_Grids_SfGrid_1_AllowFiltering) property to the ``. +* When filtering is applied, the `$filter` parameter is sent to the server. The `$filter` parameter specifies the conditions for filtering the data based on the provided criteria. The following example demonstrates how to extract the `$filter` parameter and apply filtering logic based on custom conditions: @@ -492,27 +381,22 @@ public object GetOrderData() > The `$filter` parameter can include various conditions, such as **substringof**, **eq** (equals), **gt** (greater than), and more. You can customize the filtering logic based on your specific data structure and requirements. -## Handling sorting operation - -When sorting is triggered, the `$orderby` parameter is sent to the server. The `$orderby` parameter specifies the fields to sort by, along with the sort direction (ascending or descending). +### Implement Searching Feature -The following example demonstrates how to extract the `$orderby` parameter and apply sorting logic: - -***Ascending Sorting*** - -![WebApiAdaptor - Sorting Ascending query](../images/web-api-adaptor-asc-sorting.png) +* Ensure the toolbar includes the "Search" item. +* When a search operation is triggered, the `$filter` parameter is sent to the server. The `$filter` parameter specifies the query conditions that are applied to the data to perform the search. -***Descending Sorting*** +The following example demonstrates how to extract the `$filter` parameter and apply search logic across multiple fields: -![WebApiAdaptor - Sorting Descending query](../images/web-api-adaptor-desc-sorting.png) +![WebApiAdaptor - Searching](../images/web-api-adaptor-searching.png) {% tabs %} {% highlight cs tabtitle="GridController.cs" %} /// -/// Retrieves order data and processes sorting operations based on the provided query parameters. +/// Retrieves order data and handles search operations based on the provided filter query. /// -/// Returns a JSON object containing the sorted list of orders and the total count. +/// Returns a JSON object containing the searched list of orders and the total count. [HttpGet] [Route("api/[controller]")] public object GetOrderData() @@ -523,48 +407,48 @@ public object GetOrderData() // Extract the query string from the incoming request. var queryString = Request.Query; - // Enable nullable reference types for handling sorting queries. + // Enable nullable reference types for handling filter queries. #nullable enable - string? sort = queryString["$orderby"]; + string? filterQuery = queryString["$filter"]; #nullable disable - // Check if a sorting query is provided. - if (!string.IsNullOrEmpty(sort)) + // Check if a filter query is provided. + if (!string.IsNullOrEmpty(filterQuery)) { - // Split the sorting query into individual conditions using commas as delimiters. - var sortConditions = sort.Split(','); - IOrderedEnumerable? orderedData = null; - foreach (var sortCondition in sortConditions) - { - // Split each sorting condition into field and direction (asc/desc). - var sortParts = sortCondition.Trim().Split(' '); - var sortBy = sortParts[0]; - var descending = sortParts.Length > 1 && sortParts[1].ToLower() == "desc"; - - // Define a key selector function to dynamically access the property to sort by. - Func keySelector = item => - item.GetType().GetProperty(sortBy)?.GetValue(item, null); - - // Apply sorting based on the field and direction. - orderedData = orderedData == null - ? (descending ? data.OrderByDescending(keySelector) : data.OrderBy(keySelector)) - : (descending ? orderedData.ThenByDescending(keySelector) : orderedData.ThenBy(keySelector)); - } + // Split the filter query into individual conditions using "and" as a delimiter. + var filterConditions = filterQuery.Split(new[] { " and " }, StringSplitOptions.RemoveEmptyEntries); - // Update the data with the sorted result. - if (orderedData != null) + foreach (var condition in filterConditions) { - data = orderedData.ToList(); + // Check if the condition involves a substring search. + if (condition.Contains("substringof")) + { + // Extract the search value from the substring condition. + var conditionParts = condition.Split('(', ')', '\''); + var searchValue = conditionParts[3]?.ToLower() ?? ""; + + // Filter the data based on the search value across multiple fields. + data = data.Where(order => + order != null && + (order.OrderID.ToString().Contains(searchValue) || + (order.CustomerID?.ToLower().Contains(searchValue, StringComparison.CurrentCultureIgnoreCase) ?? false) || + (order.ShipCity?.ToLower().Contains(searchValue, StringComparison.CurrentCultureIgnoreCase) ?? false) || + (order.ShipCountry?.ToLower().Contains(searchValue, StringComparison.CurrentCultureIgnoreCase) ?? false)) + ).ToList(); + } + else + { + // Handle other filtering operations here. + } } } - // Calculate the total count of records after sorting. + // Calculate the total count of records. int totalRecordsCount = data.Count(); - // Return the sorted data and the total count as a JSON object. + // Return the filtered data and the total count as a JSON object. return new { Items = data, count = totalRecordsCount }; } - {% endhighlight %} {% highlight razor tabtitle="Index.razor" %} @@ -573,7 +457,7 @@ public object GetOrderData() @using Syncfusion.Blazor.Data @using Syncfusion.Blazor - + @@ -586,23 +470,30 @@ public object GetOrderData() {% endhighlight %} {% endtabs %} -> You can parse the `$orderby` parameter to dynamically apply sorting on one or more fields in either ascending or descending order. +> This example demonstrates a custom way of handling the `$filter` query sent by the DataGrid. You can also handle it using your own logic based on the query string format or use dynamic expression evaluation libraries for a more generic approach. -## Handling paging operation +### Implement Sorting Feature -When paging is applied, the `$skip` and `$top` parameters are sent to the server. The `$skip` parameter specifies the number of records to skip, while the `$top` parameter specifies how many records to retrieve for the current page. +* Add the [AllowSorting](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Grids.SfGrid-1.html#Syncfusion_Blazor_Grids_SfGrid_1_AllowSorting) property to the ``. +* When sorting is triggered, the `$orderby` parameter is sent to the server. The `$orderby` parameter specifies the fields to sort by, along with the sort direction (ascending or descending). -The following example demonstrates how to apply paging logic: +The following example demonstrates how to extract the `$orderby` parameter and apply sorting logic: -![WebApiAdaptor - Paging](../images/web-api-adaptor-paging.png) +***Ascending Sorting*** + +![WebApiAdaptor - Sorting Ascending query](../images/web-api-adaptor-asc-sorting.png) + +***Descending Sorting*** + +![WebApiAdaptor - Sorting Descending query](../images/web-api-adaptor-desc-sorting.jpeg) {% tabs %} {% highlight cs tabtitle="GridController.cs" %} /// -/// Retrieves order data and applies paging logic based on the provided query parameters. +/// Retrieves order data and processes sorting operations based on the provided query parameters. /// -/// Returns a JSON object containing the paged list of orders and the total record count. +/// Returns a JSON object containing the sorted list of orders and the total count. [HttpGet] [Route("api/[controller]")] public object GetOrderData() @@ -613,19 +504,46 @@ public object GetOrderData() // Extract the query string from the incoming request. var queryString = Request.Query; - // Calculate the total count of records before applying paging. - int totalRecordsCount = data.Count(); + // Enable nullable reference types for handling sorting queries. + #nullable enable + string? sort = queryString["$orderby"]; + #nullable disable - // Extract the number of records to skip from the query string. - int skip = Convert.ToInt32(queryString["$skip"]); + // Check if a sorting query is provided. + if (!string.IsNullOrEmpty(sort)) + { + // Split the sorting query into individual conditions using commas as delimiters. + var sortConditions = sort.Split(','); + IOrderedEnumerable? orderedData = null; + foreach (var sortCondition in sortConditions) + { + // Split each sorting condition into field and direction (asc/desc). + var sortParts = sortCondition.Trim().Split(' '); + var sortBy = sortParts[0]; + var descending = sortParts.Length > 1 && sortParts[1].ToLower() == "desc"; - // Extract the number of records to take from the query string. - int take = Convert.ToInt32(queryString["$top"]); + // Define a key selector function to dynamically access the property to sort by. + Func keySelector = item => + item.GetType().GetProperty(sortBy)?.GetValue(item, null); - // Apply paging by skipping the specified number of records and taking the required number of records. - return take != 0 - ? new { Items = data.Skip(skip).Take(take).ToList(), Count = totalRecordsCount } - : new { Items = data, Count = totalRecordsCount }; + // Apply sorting based on the field and direction. + orderedData = orderedData == null + ? (descending ? data.OrderByDescending(keySelector) : data.OrderBy(keySelector)) + : (descending ? orderedData.ThenByDescending(keySelector) : orderedData.ThenBy(keySelector)); + } + + // Update the data with the sorted result. + if (orderedData != null) + { + data = orderedData.ToList(); + } + } + + // Calculate the total count of records after sorting. + int totalRecordsCount = data.Count(); + + // Return the sorted data and the total count as a JSON object. + return new { Items = data, count = totalRecordsCount }; } {% endhighlight %} @@ -636,7 +554,7 @@ public object GetOrderData() @using Syncfusion.Blazor.Data @using Syncfusion.Blazor - + @@ -649,15 +567,15 @@ public object GetOrderData() {% endhighlight %} {% endtabs %} -> Always calculate the total record count before applying paging. This ensures that the Grid can display the correct total number of records for pagination. +> You can parse the `$orderby` parameter to dynamically apply sorting on one or more fields in either ascending or descending order. N> If you want to handle filtering, sorting, and paging operations using Dynamic LINQ Expressions, you can refer to this [GitHub repository](https://github.com/SyncfusionExamples/blazor-datagrid-data-operations-in-wep-api-service) for an example of how to implement it dynamically. -## Handling CRUD operations +## Implement CRUD operations -To manage CRUD (Create, Read, Update, and Delete) operations using the WebApiAdaptor in Syncfusion® Blazor DataGrid, follow the provided guide for configuring the Grid for [editing](https://blazor.syncfusion.com/documentation/datagrid/editing) and utilize the sample implementation of the `GridController` in your server application. This controller handles HTTP requests for CRUD operations such as **GET, POST, PUT,** and **DELETE**. +To manage CRUD (Create, Read, Update, and Delete) operations using the WebApiAdaptor in Syncfusion® Blazor DataGrid, follow the provided guide for configuring the DataGrid for [Editing](https://blazor.syncfusion.com/documentation/datagrid/editing) and utilize the sample implementation of the `GridController` in your server application. This controller handles HTTP requests for CRUD operations such as **GET, POST, PUT,** and **DELETE**. -To enable CRUD operations in the Grid, follow the steps below: +To enable CRUD operations in the DataGrid, follow the steps below: {% tabs %} {% highlight razor tabtitle="Index.razor" %} @@ -680,11 +598,11 @@ To enable CRUD operations in the Grid, follow the steps below: {% endhighlight %} {% endtabs %} -> Normal/Inline editing is the default edit [Mode](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Grids.GridEditSettings.html#Syncfusion_Blazor_Grids_GridEditSettings_Mode) for the Grid. To enable CRUD operations, ensure that the [IsPrimaryKey](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Grids.GridColumn.html#Syncfusion_Blazor_Grids_GridColumn_IsPrimaryKey) property is set to **true** for a specific Grid column, ensuring that its value is unique. +> Normal/Inline editing is the default edit [Mode](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Grids.GridEditSettings.html#Syncfusion_Blazor_Grids_GridEditSettings_Mode) for the DataGrid. To enable CRUD operations, ensure that the [IsPrimaryKey](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Grids.GridColumn.html#Syncfusion_Blazor_Grids_GridColumn_IsPrimaryKey) property is set to **true** for a specific DataGrid column, ensuring that its value is unique. **Insert operation:** -To insert a new record into your Syncfusion® Grid, you can utilize the `HttpPost` method in your server application. The details of the newly added record are passed to the **newRecord** parameter. Below is a sample implementation of inserting a record using the **GridController**: +To insert a new record into your Syncfusion® DataGrid, you can utilize the `HttpPost` method in your server application. The details of the newly added record are passed to the **newRecord** parameter. Below is a sample implementation of inserting a record using the **GridController**: ![Insert Record](../images/web-api-adaptor-insert.png) @@ -707,7 +625,7 @@ public void Post([FromBody] OrdersDetails newRecord) **Update operation:** -Updating a record in the Syncfusion® Grid can be achieved by utilizing the `HttpPut` method in your controller. The details of the updated record are passed to the **updatedRecord** parameter. Here's a sample implementation of updating a record: +Updating a record in the Syncfusion® DataGrid can be achieved by utilizing the `HttpPut` method in your controller. The details of the updated record are passed to the **updatedRecord** parameter. Here's a sample implementation of updating a record: ![Update Record](../images/web-api-adaptor-update.png) @@ -739,7 +657,7 @@ public void Put([FromBody] OrdersDetails updatedRecord) **Delete operation:** -To delete a record from your Syncfusion® Grid, you can use the `HttpDelete` method in your controller. The primary key value of the deleted record is passed to the **deletedRecord** parameter.Below is a sample implementation: +To delete a record from your Syncfusion® DataGrid, you can use the `HttpDelete` method in your controller. The primary key value of the deleted record is passed to the **deletedRecord** parameter.Below is a sample implementation: ![Delete Record](../images/web-api-adaptor-delete.png) @@ -767,4 +685,10 @@ public void Delete(int id) ![WebApiAdaptor CRUD operations](../images/adaptor-crud-operation.gif) +N> ASP.NET Core (Blazor) Web API with batch handling is not yet supported by ASP.NET Core v3+. Therefore, it is currently not feasible to support **Batch** mode CRUD operations until ASP.NET Core provides support for batch handling. For more details, refer to [this GitHub issue](https://github.com/dotnet/aspnetcore/issues/14722). + +## Complete sample repository + +For the complete working implementation of this example, refer to the [GitHub](https://github.com/SyncfusionExamples/Binding-data-from-remote-service-to-blazor-data-grid/tree/master/WebApiAdaptor) repository. + N> ASP.NET Core (Blazor) Web API with batch handling is not yet supported by ASP.NET Core v3+. Therefore, it is currently not feasible to support **Batch** mode CRUD operations until ASP.NET Core provides support for batch handling. For more details, refer to [this GitHub issue](https://github.com/dotnet/aspnetcore/issues/14722). \ No newline at end of file diff --git a/blazor/datagrid/images/urladaptor-batch-editing.gif b/blazor/datagrid/images/urladaptor-batch-editing.gif index fb4068f1af..0c99d0f83e 100644 Binary files a/blazor/datagrid/images/urladaptor-batch-editing.gif and b/blazor/datagrid/images/urladaptor-batch-editing.gif differ diff --git a/blazor/datagrid/images/web-api-adaptor-asc-sorting.png b/blazor/datagrid/images/web-api-adaptor-asc-sorting.png index 91c6bba114..2538a18d8d 100644 Binary files a/blazor/datagrid/images/web-api-adaptor-asc-sorting.png and b/blazor/datagrid/images/web-api-adaptor-asc-sorting.png differ diff --git a/blazor/datagrid/images/web-api-adaptor-desc-sorting.jpeg b/blazor/datagrid/images/web-api-adaptor-desc-sorting.jpeg new file mode 100644 index 0000000000..b3759b20c1 Binary files /dev/null and b/blazor/datagrid/images/web-api-adaptor-desc-sorting.jpeg differ diff --git a/blazor/datagrid/images/web-api-adaptor-insert.png b/blazor/datagrid/images/web-api-adaptor-insert.png index 4001815359..4c8adc28a9 100644 Binary files a/blazor/datagrid/images/web-api-adaptor-insert.png and b/blazor/datagrid/images/web-api-adaptor-insert.png differ diff --git a/blazor/datagrid/images/web-api-adaptor-searching.png b/blazor/datagrid/images/web-api-adaptor-searching.png index 20fae8f453..8299c1d789 100644 Binary files a/blazor/datagrid/images/web-api-adaptor-searching.png and b/blazor/datagrid/images/web-api-adaptor-searching.png differ diff --git a/blazor/datagrid/images/web-api-adaptor-update.png b/blazor/datagrid/images/web-api-adaptor-update.png index ce90416449..9e488f1817 100644 Binary files a/blazor/datagrid/images/web-api-adaptor-update.png and b/blazor/datagrid/images/web-api-adaptor-update.png differ