diff --git a/blazor-toc.html b/blazor-toc.html index f081b91a8f..b87822b9cb 100644 --- a/blazor-toc.html +++ b/blazor-toc.html @@ -1832,6 +1832,7 @@
  • Connecting to Adaptors
  • diff --git a/blazor/datagrid/connecting-to-adaptors/url-adaptor.md b/blazor/datagrid/connecting-to-adaptors/url-adaptor.md new file mode 100644 index 0000000000..014d15b314 --- /dev/null +++ b/blazor/datagrid/connecting-to-adaptors/url-adaptor.md @@ -0,0 +1,845 @@ +--- +layout: post +title: Bind data and perform CRUD action with UrlAdaptor in Syncfusion Blazor DataGrid +description: Learn about bind data and performing CRUD operations using UrlAdaptor in Syncfusion Blazor DataGrid. +platform: Blazor +control: DataGrid +keywords: adaptors, urladaptor, url adaptor, remotedata +documentation: ug +--- + +# UrlAdaptor in Syncfusion Blazor DataGrid + +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. + +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. + +## 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). + +**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(); + + 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; + } + + 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. + +**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) + +## 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. + +```razor +@using Syncfusion.Blazor +@using Syncfusion.Blazor.Grids +``` + +- Register the Syncfusion Blazor service in the **~/Program.cs** file. + +```csharp +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. + +**3. Add stylesheet and script resources** + +Include the theme stylesheet and script references in the **~/Components/App.razor** file. + +```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" %} + +@using Syncfusion.Blazor.Grids +@using Syncfusion.Blazor.Data +@using URLAdaptor.Models + + + + + + + + + + + +{% endhighlight %} + +{% highlight cs tabtitle="GridController.cs" %} + +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 searching, filtering, sorting, paging, and returns the processed data. + /// + /// The request object contains data operation parameters such as search, filter, sort, and pagination details. + /// 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 }; + } + } +} + +{% 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. + +![UrlAdaptor Data](../images/blazor-datagrid-adaptors.gif) + +> * 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 + +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. + +![UrlAdaptor - Searching](../images/urladaptor-searching.png) + +{% tabs %} +{% highlight cs tabtitle="GridController.cs" %} + +/// +/// Handles server-side data operations such as searching and returns the processed data. +/// +/// The request object contains searched details. +/// Returns a response containing the processed data and the total record count. +[HttpPost] +[Route("api/[controller]")] +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) + { + DataSource = DataOperations.PerformSearching(DataSource, DataManagerRequest.Search); + // 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 }; +} + +{% endhighlight %} + +{% highlight razor tabtitle="Index.razor" %} + +@using Syncfusion.Blazor.Grids +@using Syncfusion.Blazor.Data +@using URLAdaptor.Models + + + + + + + + + + + +{% endhighlight %} +{% endtabs %} + +### Handling filtering operation + +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. + +**Single column filtering** +![Single column filtering](../images/urladaptor-filtering.png) + +**Multi column filtering** +![Multi column filtering](../images/urladaptor-multi-filtering.png) + +{% tabs %} +{% highlight cs tabtitle="GridController.cs" %} + +/// +/// Handles server-side data operations such as filtering and returns the processed data. +/// +/// The request object contains filtered details. +/// Returns a response containing the processed data and the total record count. +[HttpPost] +[Route("api/[controller]")] +public object Post([FromBody] DataManagerRequest DataManagerRequest) +{ + // Retrieve data from the data source. + IQueryable DataSource = GetOrderData().AsQueryable(); + + // Handling filtering operation. + if (DataManagerRequest.Where != null && DataManagerRequest.Where.Count > 0) + { + foreach (var condition in DataManagerRequest.Where) + { + foreach (var predicate in condition.predicates) + { + DataSource = DataOperations.PerformFiltering(DataSource, DataManagerRequest.Where, predicate.Operator); + // 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 }; +} + +{% endhighlight %} + +{% highlight razor tabtitle="Index.razor" %} + +@using Syncfusion.Blazor.Grids +@using Syncfusion.Blazor.Data +@using URLAdaptor.Models + + + + + + + + + + + +{% endhighlight %} +{% endtabs %} + +## Handling sorting operation + +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. + +**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 sorting and returns the processed data. +/// +/// The request object contains sorted details. +/// Returns a response containing the processed data and the total record count. +[HttpPost] +[Route("api/[controller]")] +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) + { + 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 }; +} + +{% endhighlight %} + +{% highlight razor tabtitle="Index.razor" %} + +@using Syncfusion.Blazor.Grids +@using Syncfusion.Blazor.Data +@using URLAdaptor.Models + + + + + + + + + + + +{% endhighlight %} +{% endtabs %} + +## Handling paging operation + +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. + +![UrlAdaptor - Paging](../images/urladaptor-paging.png) + +{% tabs %} +{% highlight cs tabtitle="GridController.cs" %} + +/// +/// Handles server-side data operations such as paging and returns the processed data. +/// +/// The request object contains pagination details. +/// Returns a response containing the processed data and the total record count. +[HttpPost] +[Route("api/[controller]")] +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) + { + DataSource = DataOperations.PerformTake(DataSource, DataManagerRequest.Take); + // Add custom logic here if needed and remove above method. + } + + // Return data based on the request. + return new { result = DataSource, count = totalRecordsCount }; +} + +{% endhighlight %} + +{% highlight razor tabtitle="Index.razor" %} + +@using Syncfusion.Blazor.Grids +@using Syncfusion.Blazor.Data +@using URLAdaptor.Models + + + + + + + + + + + +{% endhighlight %} +{% endtabs %} + +## Handling 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 Grid to communicate with the data service for every Grid action, facilitating server-side operations. + +**CRUD Operations Mapping** + +CRUD operations within the Grid 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. + +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. + +{% tabs %} +{% highlight razor tabtitle="Index.razor" %} + +@using Syncfusion.Blazor.Grids +@using Syncfusion.Blazor.Data +@using URLAdaptor.Models + + + + + + + + + + + + +{% 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. + +The below class is used to structure data sent during CRUD operations. + +```cs +public class CRUDModel where T : class +{ + public string? action { get; set; } + public string? keyColumn { get; set; } + public object? key { get; set; } + public T? value { get; set; } + public List? added { get; set; } + public List? changed { get; set; } + public List? deleted { get; set; } + public IDictionary? @params { get; set; } +} +``` + +**Insert operation:** + +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. + +![Insert Record](../images/urladaptor-insert-record.png) + +{% tabs %} +{% highlight cs tabtitle="GridController.cs" %} + +/// +/// Inserts a new data item into the data collection. +/// +/// It contains the new record detail which is need to be inserted. +/// Returns void. +[HttpPost] +[Route("api/[controller]/Insert")] +public void Insert([FromBody] CRUDModel newRecord) +{ + if (newRecord.value != null) + { + // Add the new record to the data collection. + OrdersDetails.GetAllRecords().Insert(0, newRecord.value); + } +} + +{% endhighlight %} +{% endtabs %} + +**Update operation:** + +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. + +![Update Record](../images/urladaptor-update-record.png) + +{% tabs %} +{% highlight cs tabtitle="GridController.cs" %} + +/// +/// Update a existing data item from the data collection. +/// +/// It contains the updated record detail which is need to be updated. +/// Returns void. +[HttpPost] +[Route("api/[controller]/Update")] +public void Update([FromBody] CRUDModel updatedRecord) +{ + var updatedOrder = updatedRecord.value; + if (updatedOrder != null) + { + var data = OrdersDetails.GetAllRecords().FirstOrDefault(or => or.OrderID == updatedOrder.OrderID); + if (data != null) + { + // Update the existing record. + data.OrderID = updatedOrder.OrderID; + data.CustomerID = updatedOrder.CustomerID; + data.ShipCity = updatedOrder.ShipCity; + data.ShipCountry = updatedOrder.ShipCountry; + // Update other properties similarly. + } + } +} + +{% endhighlight %} +{% endtabs %} + +**Delete operation:** + +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. + +![Delete Record](../images/urladaptor-delete-record.png) + +{% tabs %} +{% highlight cs tabtitle="GridController.cs" %} + +/// +/// Remove a specific data item from the data collection. +/// +/// It contains the specific record detail which is need to be removed. +/// Returns void. +[HttpPost] +[Route("api/[controller]/Remove")] +public void Remove([FromBody] CRUDModel deletedRecord) +{ + // Get the key value from the deletedRecord. + int orderId = int.Parse(deletedRecord.key.ToString()); + var data = OrdersDetails.GetAllRecords().FirstOrDefault(orderData => orderData.OrderID == orderId); + if (data != null) + { + // Remove the record from the data collection. + OrdersDetails.GetAllRecords().Remove(data); + } +} + +{% endhighlight %} +{% endtabs %} + +![UrlAdaptor CRUD operations](../images/adaptor-crud-operation.gif) + +**Single method for performing all CRUD operations:** + +Using the [CrudUrl](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.DataManager.html#Syncfusion_Blazor_DataManager_CrudUrl) property, the controller action mapping URL can be specified to perform all CRUD operations on the server side using a single method, instead of specifying separate controller action methods for CRUD (Insert, Update, and Delete) operations. + +The following code example illustrates this behavior. + +{% tabs %} +{% highlight cs tabtitle="GridController.cs" %} + +/// +/// Handles CRUD (Create, Read, Update, and Delete) operations for a single request using the specified CRUD URL. +/// +/// An object containing the details of the record to be processed and the action to be performed (e.g., Create, Read, Update, and Delete). +/// A response indicating the result of the CRUD operation, including success or failure details. +[HttpPost] +[Route("api/[controller]/CrudUpdate")] +public void CrudUpdate([FromBody] CRUDModel request) +{ + // Perform the update operation. + if (request.action == "update") + { + var orderValue = request.value; + OrdersDetails existingRecord = OrdersDetails.GetAllRecords().FirstOrDefault(or => or.OrderID == orderValue.OrderID); + if (existingRecord != null) + { + // Update the properties of the existing record. + existingRecord.OrderID = orderValue.OrderID; + existingRecord.CustomerID = orderValue.CustomerID; + existingRecord.ShipCity = orderValue.ShipCity; + existingRecord.ShipCountry = orderValue.ShipCountry; + // Update other properties as needed. + } + } + // Perform the insert operation. + else if (request.action == "insert") + { + // Add the new record to the data collection. + OrdersDetails.GetAllRecords().Insert(0, request.value); + } + // Perform the remove operation. + else if (request.action == "remove") + { + // Remove the record from the data collection. + OrdersDetails.GetAllRecords().Remove(OrdersDetails.GetAllRecords().FirstOrDefault(or => or.OrderID == int.Parse(request.key.ToString()))); + } +} + +{% endhighlight %} + +{% highlight razor tabtitle="Index.razor" %} + +@using Syncfusion.Blazor.Grids +@using Syncfusion.Blazor.Data +@using URLAdaptor.Models + + + + + + + + + + + + +{% endhighlight %} +{% endtabs %} + +**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. + +{% tabs %} +{% highlight cs tabtitle="GridController.cs" %} + +/// +/// Handles CRUD operations when batch editing is enabled in the DataGrid. +/// +/// The batch model containing the data changes to be processed. +/// Returns the result of the CRUD operation. +[HttpPost] +[Route("api/[controller]/BatchUpdate")] +public IActionResult BatchUpdate([FromBody] CRUDModel batchModel) +{ + // Check if there are any added records in the batch model. + if (batchModel.added != null) + { + // Iterate through each added record. + foreach (var Record in batchModel.added) + { + // Insert the added record at the beginning of the existing records. + OrdersDetails.GetAllRecords().Insert(0, Record); + } + } + // Check if there are any changed records in the batch model. + if (batchModel.changed != null) + { + // Iterate through each changed record. + foreach (var changedOrder in batchModel.changed) + { + // Find the existing record that matches the changed record's "OrderID". + var existingOrder = OrdersDetails.GetAllRecords().FirstOrDefault(or => or.OrderID == changedOrder.OrderID); + if (existingOrder != null) + { + // Update the properties of the existing record. + existingOrder.OrderID = changedOrder.OrderID; + existingOrder.CustomerID = changedOrder.CustomerID; + existingOrder.ShipCity = changedOrder.ShipCity; + existingOrder.ShipCountry = changedOrder.ShipCity; + // Update other properties as needed. + } + } + } + // Check if there are any deleted records in the batch model. + if (batchModel.deleted != null) + { + // Iterate through each deleted record. + foreach (var deletedOrder in batchModel.deleted) + { + // Find the existing record that matches the deleted record's "OrderID". + var orderToDelete = OrdersDetails.GetAllRecords().FirstOrDefault(or => or.OrderID == deletedOrder.OrderID); + if (orderToDelete != null) + { + // Remove the matching record from the existing records. + OrdersDetails.GetAllRecords().Remove(orderToDelete); + } + } + } + + // Return the updated batch model as a JSON result. + return new JsonResult(batchModel); +} + +{% endhighlight %} + +{% highlight razor tabtitle="Index.razor" %} + +@using Syncfusion.Blazor.Grids +@using Syncfusion.Blazor.Data +@using URLAdaptor.Models + + + + + + + + + + + + +{% endhighlight %} +{% endtabs %} + +![UrlAdaptor - Batch Editing](../images/urladaptor-batch-editing.gif) \ No newline at end of file diff --git a/blazor/datagrid/images/adaptor-crud-operation.gif b/blazor/datagrid/images/adaptor-crud-operation.gif new file mode 100644 index 0000000000..309278c03d Binary files /dev/null and b/blazor/datagrid/images/adaptor-crud-operation.gif differ diff --git a/blazor/datagrid/images/blazor-datagrid-adaptors-data.png b/blazor/datagrid/images/blazor-datagrid-adaptors-data.png new file mode 100644 index 0000000000..ffcda9bc76 Binary files /dev/null and b/blazor/datagrid/images/blazor-datagrid-adaptors-data.png differ diff --git a/blazor/datagrid/images/blazor-datagrid-adaptors.gif b/blazor/datagrid/images/blazor-datagrid-adaptors.gif new file mode 100644 index 0000000000..12a584bffb Binary files /dev/null and b/blazor/datagrid/images/blazor-datagrid-adaptors.gif differ diff --git a/blazor/datagrid/images/urladaptor-batch-editing.gif b/blazor/datagrid/images/urladaptor-batch-editing.gif new file mode 100644 index 0000000000..fb4068f1af Binary files /dev/null and b/blazor/datagrid/images/urladaptor-batch-editing.gif differ diff --git a/blazor/datagrid/images/urladaptor-delete-record.png b/blazor/datagrid/images/urladaptor-delete-record.png new file mode 100644 index 0000000000..b3eeb35d05 Binary files /dev/null and b/blazor/datagrid/images/urladaptor-delete-record.png differ diff --git a/blazor/datagrid/images/urladaptor-filtering.png b/blazor/datagrid/images/urladaptor-filtering.png new file mode 100644 index 0000000000..4caa6e72ce Binary files /dev/null and b/blazor/datagrid/images/urladaptor-filtering.png differ diff --git a/blazor/datagrid/images/urladaptor-insert-record.png b/blazor/datagrid/images/urladaptor-insert-record.png new file mode 100644 index 0000000000..5eed63b670 Binary files /dev/null and b/blazor/datagrid/images/urladaptor-insert-record.png differ diff --git a/blazor/datagrid/images/urladaptor-multi-filtering.png b/blazor/datagrid/images/urladaptor-multi-filtering.png new file mode 100644 index 0000000000..e081d4eb3b Binary files /dev/null and b/blazor/datagrid/images/urladaptor-multi-filtering.png differ diff --git a/blazor/datagrid/images/urladaptor-multi-sorting.png b/blazor/datagrid/images/urladaptor-multi-sorting.png new file mode 100644 index 0000000000..6b15128180 Binary files /dev/null and b/blazor/datagrid/images/urladaptor-multi-sorting.png differ diff --git a/blazor/datagrid/images/urladaptor-paging.png b/blazor/datagrid/images/urladaptor-paging.png new file mode 100644 index 0000000000..b28d577f6b Binary files /dev/null and b/blazor/datagrid/images/urladaptor-paging.png differ diff --git a/blazor/datagrid/images/urladaptor-searching.png b/blazor/datagrid/images/urladaptor-searching.png new file mode 100644 index 0000000000..2a07905980 Binary files /dev/null and b/blazor/datagrid/images/urladaptor-searching.png differ diff --git a/blazor/datagrid/images/urladaptor-sorting.png b/blazor/datagrid/images/urladaptor-sorting.png new file mode 100644 index 0000000000..46421e378f Binary files /dev/null and b/blazor/datagrid/images/urladaptor-sorting.png differ diff --git a/blazor/datagrid/images/urladaptor-update-record.png b/blazor/datagrid/images/urladaptor-update-record.png new file mode 100644 index 0000000000..bc38a88cf6 Binary files /dev/null and b/blazor/datagrid/images/urladaptor-update-record.png differ