diff --git a/CustomAdaptor/CustomAdaptor/Controllers/OrdersController.cs b/CustomAdaptor/CustomAdaptor/Controllers/OrdersController.cs
new file mode 100644
index 0000000..619cf31
--- /dev/null
+++ b/CustomAdaptor/CustomAdaptor/Controllers/OrdersController.cs
@@ -0,0 +1,78 @@
+using CustomAdaptor.Models;
+using Microsoft.AspNetCore.Mvc;
+using Microsoft.AspNetCore.OData.Query;
+
+namespace CustomAdaptor.Controllers
+{
+ public class OrdersController : Controller
+ {
+ ///
+ /// Retrieves all orders.
+ ///
+ /// The collection of orders.
+ [HttpGet]
+ [EnableQuery]
+ public IActionResult Get()
+ {
+ var data = OrdersDetails.GetAllRecords().AsQueryable();
+ return Ok(data);
+ }
+
+ ///
+ /// Inserts a new order to the collection.
+ ///
+ /// The order to be inserted.
+ /// It returns the newly inserted record detail.
+ [HttpPost]
+ [EnableQuery]
+ public IActionResult Post([FromBody] OrdersDetails addRecord)
+ {
+ if (addRecord == null)
+ {
+ return BadRequest("Null order");
+ }
+ OrdersDetails.GetAllRecords().Insert(0, addRecord);
+ return Json(addRecord);
+ }
+
+ ///
+ /// Updates an existing order.
+ ///
+ /// The ID of the order to update.
+ /// The updated order details.
+ /// It returns the updated order details.
+ [HttpPatch("{key}")]
+ public IActionResult Patch(int key, [FromBody] OrdersDetails updateRecord)
+ {
+ if (updateRecord == null)
+ {
+ return BadRequest("No records");
+ }
+ var existingOrder = OrdersDetails.GetAllRecords().FirstOrDefault(order => order.OrderID == key);
+ if (existingOrder != null)
+ {
+ // If the order exists, update its properties
+ existingOrder.CustomerID = updateRecord.CustomerID ?? existingOrder.CustomerID;
+ existingOrder.EmployeeID = updateRecord.EmployeeID ?? existingOrder.EmployeeID;
+ existingOrder.ShipCountry = updateRecord.ShipCountry ?? existingOrder.ShipCountry;
+ }
+ return Json(updateRecord);
+ }
+
+ ///
+ /// Deletes an order.
+ ///
+ /// The ID of the order to delete.
+ /// It returns the deleted record detail
+ [HttpDelete("{key}")]
+ public IActionResult Delete(int key)
+ {
+ var deleteRecord = OrdersDetails.GetAllRecords().FirstOrDefault(order => order.OrderID == key);
+ if (deleteRecord != null)
+ {
+ OrdersDetails.GetAllRecords().Remove(deleteRecord);
+ }
+ return Json(deleteRecord);
+ }
+ }
+}
diff --git a/CustomAdaptor/CustomAdaptor/Controllers/WeatherForecastController.cs b/CustomAdaptor/CustomAdaptor/Controllers/WeatherForecastController.cs
new file mode 100644
index 0000000..ac7d821
--- /dev/null
+++ b/CustomAdaptor/CustomAdaptor/Controllers/WeatherForecastController.cs
@@ -0,0 +1,33 @@
+using Microsoft.AspNetCore.Mvc;
+
+namespace CustomAdaptor.Controllers
+{
+ [ApiController]
+ [Route("[controller]")]
+ public class WeatherForecastController : ControllerBase
+ {
+ private static readonly string[] Summaries = new[]
+ {
+ "Freezing", "Bracing", "Chilly", "Cool", "Mild", "Warm", "Balmy", "Hot", "Sweltering", "Scorching"
+ };
+
+ private readonly ILogger _logger;
+
+ public WeatherForecastController(ILogger logger)
+ {
+ _logger = logger;
+ }
+
+ [HttpGet(Name = "GetWeatherForecast")]
+ public IEnumerable Get()
+ {
+ return Enumerable.Range(1, 5).Select(index => new WeatherForecast
+ {
+ Date = DateOnly.FromDateTime(DateTime.Now.AddDays(index)),
+ TemperatureC = Random.Shared.Next(-20, 55),
+ Summary = Summaries[Random.Shared.Next(Summaries.Length)]
+ })
+ .ToArray();
+ }
+ }
+}
diff --git a/CustomAdaptor/CustomAdaptor/CustomAdaptor.csproj b/CustomAdaptor/CustomAdaptor/CustomAdaptor.csproj
new file mode 100644
index 0000000..60250ee
--- /dev/null
+++ b/CustomAdaptor/CustomAdaptor/CustomAdaptor.csproj
@@ -0,0 +1,14 @@
+
+
+
+ net8.0
+ enable
+ enable
+
+
+
+
+
+
+
+
diff --git a/CustomAdaptor/CustomAdaptor/CustomAdaptor.csproj.user b/CustomAdaptor/CustomAdaptor/CustomAdaptor.csproj.user
new file mode 100644
index 0000000..9ff5820
--- /dev/null
+++ b/CustomAdaptor/CustomAdaptor/CustomAdaptor.csproj.user
@@ -0,0 +1,6 @@
+
+
+
+ https
+
+
\ No newline at end of file
diff --git a/CustomAdaptor/CustomAdaptor/CustomAdaptor.http b/CustomAdaptor/CustomAdaptor/CustomAdaptor.http
new file mode 100644
index 0000000..37e5c1f
--- /dev/null
+++ b/CustomAdaptor/CustomAdaptor/CustomAdaptor.http
@@ -0,0 +1,6 @@
+@CustomAdaptor_HostAddress = http://localhost:5286
+
+GET {{CustomAdaptor_HostAddress}}/weatherforecast/
+Accept: application/json
+
+###
diff --git a/CustomAdaptor/CustomAdaptor/CustomAdaptor.sln b/CustomAdaptor/CustomAdaptor/CustomAdaptor.sln
new file mode 100644
index 0000000..d859c19
--- /dev/null
+++ b/CustomAdaptor/CustomAdaptor/CustomAdaptor.sln
@@ -0,0 +1,25 @@
+
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio Version 17
+VisualStudioVersion = 17.13.35919.96 d17.13
+MinimumVisualStudioVersion = 10.0.40219.1
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CustomAdaptor", "CustomAdaptor.csproj", "{94144981-A808-4936-9BE1-BABA4C056FA8}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Any CPU = Debug|Any CPU
+ Release|Any CPU = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {94144981-A808-4936-9BE1-BABA4C056FA8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {94144981-A808-4936-9BE1-BABA4C056FA8}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {94144981-A808-4936-9BE1-BABA4C056FA8}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {94144981-A808-4936-9BE1-BABA4C056FA8}.Release|Any CPU.Build.0 = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+ GlobalSection(ExtensibilityGlobals) = postSolution
+ SolutionGuid = {5F94210D-948B-4031-A1AC-5D39E7CEEB4C}
+ EndGlobalSection
+EndGlobal
diff --git a/CustomAdaptor/CustomAdaptor/Models/OrdersDetails.cs b/CustomAdaptor/CustomAdaptor/Models/OrdersDetails.cs
new file mode 100644
index 0000000..73851c8
--- /dev/null
+++ b/CustomAdaptor/CustomAdaptor/Models/OrdersDetails.cs
@@ -0,0 +1,44 @@
+using System.ComponentModel.DataAnnotations;
+
+namespace CustomAdaptor.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; }
+ }
+}
diff --git a/CustomAdaptor/CustomAdaptor/Program.cs b/CustomAdaptor/CustomAdaptor/Program.cs
new file mode 100644
index 0000000..dc59570
--- /dev/null
+++ b/CustomAdaptor/CustomAdaptor/Program.cs
@@ -0,0 +1,50 @@
+using CustomAdaptor.Models;
+using Microsoft.AspNetCore.OData;
+using Microsoft.OData.ModelBuilder;
+
+
+var builder = WebApplication.CreateBuilder(args);
+
+// Add services to the container.
+
+builder.Services.AddControllers();
+// Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle
+builder.Services.AddEndpointsApiExplorer();
+builder.Services.AddSwaggerGen();
+
+// Create an ODataConventionModelBuilder to build the OData model
+var modelBuilder = new ODataConventionModelBuilder();
+
+// Register the "Orders" entity set with the OData model builder
+modelBuilder.EntitySet("Orders");
+
+// Add controllers with OData support to the service collection
+
+var recordCount = OrdersDetails.GetAllRecords().Count;
+builder.Services.AddControllers().AddOData(
+ options => options
+ .Count()
+ .Filter() //searching and filtering
+ .Select()
+ .Expand()
+ .OrderBy()
+ .SetMaxTop(recordCount)
+ .AddRouteComponents("odata", modelBuilder.GetEdmModel()));
+
+var app = builder.Build();
+app.UseDefaultFiles();
+app.UseStaticFiles();
+// Configure the HTTP request pipeline.
+if (app.Environment.IsDevelopment())
+{
+ app.UseSwagger();
+ app.UseSwaggerUI();
+}
+
+app.UseHttpsRedirection();
+
+app.UseAuthorization();
+
+app.MapControllers();
+
+app.Run();
\ No newline at end of file
diff --git a/CustomAdaptor/CustomAdaptor/Properties/launchSettings.json b/CustomAdaptor/CustomAdaptor/Properties/launchSettings.json
new file mode 100644
index 0000000..e223da7
--- /dev/null
+++ b/CustomAdaptor/CustomAdaptor/Properties/launchSettings.json
@@ -0,0 +1,41 @@
+{
+ "$schema": "http://json.schemastore.org/launchsettings.json",
+ "iisSettings": {
+ "windowsAuthentication": false,
+ "anonymousAuthentication": true,
+ "iisExpress": {
+ "applicationUrl": "http://localhost:26717",
+ "sslPort": 44324
+ }
+ },
+ "profiles": {
+ "http": {
+ "commandName": "Project",
+ "dotnetRunMessages": true,
+ "launchBrowser": true,
+ "launchUrl": "swagger",
+ "applicationUrl": "http://localhost:5286",
+ "environmentVariables": {
+ "ASPNETCORE_ENVIRONMENT": "Development"
+ }
+ },
+ "https": {
+ "commandName": "Project",
+ "dotnetRunMessages": true,
+ "launchBrowser": true,
+ "launchUrl": "swagger",
+ "applicationUrl": "https://localhost:7295;http://localhost:5286",
+ "environmentVariables": {
+ "ASPNETCORE_ENVIRONMENT": "Development"
+ }
+ },
+ "IIS Express": {
+ "commandName": "IISExpress",
+ "launchBrowser": true,
+ "launchUrl": "swagger",
+ "environmentVariables": {
+ "ASPNETCORE_ENVIRONMENT": "Development"
+ }
+ }
+ }
+}
diff --git a/CustomAdaptor/CustomAdaptor/WeatherForecast.cs b/CustomAdaptor/CustomAdaptor/WeatherForecast.cs
new file mode 100644
index 0000000..1e0949e
--- /dev/null
+++ b/CustomAdaptor/CustomAdaptor/WeatherForecast.cs
@@ -0,0 +1,13 @@
+namespace CustomAdaptor
+{
+ public class WeatherForecast
+ {
+ public DateOnly Date { get; set; }
+
+ public int TemperatureC { get; set; }
+
+ public int TemperatureF => 32 + (int)(TemperatureC / 0.5556);
+
+ public string? Summary { get; set; }
+ }
+}
diff --git a/CustomAdaptor/CustomAdaptor/appsettings.Development.json b/CustomAdaptor/CustomAdaptor/appsettings.Development.json
new file mode 100644
index 0000000..0c208ae
--- /dev/null
+++ b/CustomAdaptor/CustomAdaptor/appsettings.Development.json
@@ -0,0 +1,8 @@
+{
+ "Logging": {
+ "LogLevel": {
+ "Default": "Information",
+ "Microsoft.AspNetCore": "Warning"
+ }
+ }
+}
diff --git a/CustomAdaptor/CustomAdaptor/appsettings.json b/CustomAdaptor/CustomAdaptor/appsettings.json
new file mode 100644
index 0000000..10f68b8
--- /dev/null
+++ b/CustomAdaptor/CustomAdaptor/appsettings.json
@@ -0,0 +1,9 @@
+{
+ "Logging": {
+ "LogLevel": {
+ "Default": "Information",
+ "Microsoft.AspNetCore": "Warning"
+ }
+ },
+ "AllowedHosts": "*"
+}
diff --git a/CustomAdaptor/CustomAdaptor/wwwroot/index.html b/CustomAdaptor/CustomAdaptor/wwwroot/index.html
new file mode 100644
index 0000000..8b9e28b
--- /dev/null
+++ b/CustomAdaptor/CustomAdaptor/wwwroot/index.html
@@ -0,0 +1,30 @@
+
+
+
+ EJ2 Grid
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/CustomAdaptor/CustomAdaptor/wwwroot/js/CustomAdaptor.js b/CustomAdaptor/CustomAdaptor/wwwroot/js/CustomAdaptor.js
new file mode 100644
index 0000000..7cbf30d
--- /dev/null
+++ b/CustomAdaptor/CustomAdaptor/wwwroot/js/CustomAdaptor.js
@@ -0,0 +1,22 @@
+export class CustomAdaptor extends ej.data.ODataV4Adaptor {
+ processQuery(dm, query) {
+ dm.dataSource.url = 'https://localhost:7295/odata/orders'; //Change the url.
+ query.addParams('Syncfusion Grid', 'true'); // Add the additional parameter.
+ return super.processQuery.apply(this, arguments);
+ }
+
+ beforeSend(dm, request, settings) {
+ request.headers.set('Authorization', `true`);
+ super.beforeSend(dm, request, settings);
+ }
+
+ processResponse() {
+ let i = 0;
+ const original = super.processResponse.apply(this, arguments);
+ // Adding serial number.
+ if (original.result) {
+ original.result.forEach((item) => ej.base.setValue('SNo', ++i, item));
+ }
+ return original;
+ }
+}
\ No newline at end of file
diff --git a/CustomAdaptor/CustomAdaptor/wwwroot/js/index.js b/CustomAdaptor/CustomAdaptor/wwwroot/js/index.js
new file mode 100644
index 0000000..3e96d99
--- /dev/null
+++ b/CustomAdaptor/CustomAdaptor/wwwroot/js/index.js
@@ -0,0 +1,26 @@
+
+import { CustomAdaptor } from './CustomAdaptor.js';
+
+ej.grids.Grid.Inject(ej.grids.Toolbar, ej.grids.Filter, ej.grids.Sort, ej.grids.Page, ej.grids.Edit);
+
+var data = new ej.data.DataManager({
+ url: 'https://localhost:7295/odata/orders', // Here xxxx represents the port number
+ adaptor: new CustomAdaptor()
+});
+
+var grid = new ej.grids.Grid({
+ dataSource: data,
+ allowPaging:true,
+ allowFiltering: true,
+ allowSorting: true,
+ toolbar: ['Add', 'Edit', 'Update', 'Delete', 'Cancel', 'Search'],
+ editSettings: { allowAdding: true, allowDeleting: true, allowEditing: true },
+ columns: [
+ { field: 'OrderID', headerText: 'Order ID', textAlign: 'Right', width: 120, isPrimaryKey: true, type: 'number' },
+ { field: 'CustomerID', width: 140, headerText: 'Customer ID', type: 'string' },
+ { field: 'EmployeeID', headerText: 'Employee ID', width: 140 },
+ { field: 'ShipCountry', headerText: 'ShipCountry', width: 140 }
+ ]
+});
+
+grid.appendTo('#Grid');
\ No newline at end of file
diff --git a/CustomAdaptor/README.md b/CustomAdaptor/README.md
new file mode 100644
index 0000000..600152e
--- /dev/null
+++ b/CustomAdaptor/README.md
@@ -0,0 +1,31 @@
+# CustomAdaptor in Syncfusion Grid
+
+The CustomAdaptor in Syncfusion Grid allows to create their own custom adaptors by extending the built-in adaptors. The custom adaptor involves handling the query process, requests, and responses of the built-in adaptor. The CustomAdaptor can be used to extend OData V4 services, enabling efficient data fetching and manipulation.
+
+## Getting Started
+
+**1. Clone the Repository:**
+
+Use `git clone` to fetch the repository from GitHub.
+
+```bash
+https://github.com/SyncfusionExamples/Binding-data-from-remote-service-to-javascript-data-grid.git
+```
+
+**2. Open and Build the Project:**
+
+* Open the project in Visual Studio.
+* Build the project to restore dependencies and compile it.
+* Run the project
+
+**3. Explore the Code:**
+
+* Navigate to JavaScript files (typically in wwwroot).
+* Debug and interact with the code as needed.
+
+## Resources
+
+You can also refer the below resources to know more details about Syncfusion Javascript Grid components.
+
+* [Demo](https://ej2.syncfusion.com/javascript/demos/#/bootstrap/grid/over-view)
+* [Documentation](https://ej2.syncfusion.com/javascript/documentation/grid/getting-started)
\ No newline at end of file