Bind Grid to OData-v4 Using WebAPI Controller
Environment
Product | Telerik UI for ASP.NET MVC Grid |
Product version | 2025.1.227 |
Description
How can I bind the Grid to OData-v4 using WebAPI endpoints?
Solution
OData-v4 is not fully supported, and the approaches for processing DateTime
properties are limited.
The reason is that WebAPI does not support the DateTime
data type any more. Instead, WebAPI now uses the DateTimeOffset
type as a main data type when it comes to dates. However, to keep information for both date and offset, the DateTimeOffet
requires the Model (that the DataSource creates), which is not possible with the current architecture of the DataSource and Model.
You can achieve this requirement using the following implementation:
-
Configure the Grid's DataSource as per the example below:
Razor.DataSource(dataSource => dataSource .Custom() .Batch(true) .Schema(sch => { sch.Model(m=>{ m.Id("ProductID"); m.Field(f=>f.ProductID).Editable(false); m.Field("UnitPrice", typeof(Decimal)); }); }) .Type("odata-v4") .Transport(t => { t.Read(new { url = new Kendo.Mvc.ClientHandlerDescriptor() { HandlerName = "readProduct" } }); t.Update(new { url = new Kendo.Mvc.ClientHandlerDescriptor() { HandlerName = "updateProduct" } }); t.Create(new { url = new Kendo.Mvc.ClientHandlerDescriptor() { HandlerName = "createProduct" } }); t.Destroy(new { url = new Kendo.Mvc.ClientHandlerDescriptor() { HandlerName = "destroyProduct" } }); t.Batch(new { url = new Kendo.Mvc.ClientHandlerDescriptor() { HandlerName = "batchProduct" } }); }) .PageSize(20) .ServerPaging(true) .ServerSorting(true) .ServerFiltering(true) )
-
Define the JavaScript functions that return the respective URL:
JSfunction batchProduct() { return "https://demos.telerik.com/kendo-ui/service-v4/odata/$batch"; } function readProduct() { return "https://demos.telerik.com/kendo-ui/service-v4/odata/Products"; } function updateProduct(dataItem) { return "https://demos.telerik.com/kendo-ui/service-v4/odata/Products(" + dataItem.ProductID + ")"; } function createProduct(dataItem) { delete dataItem.ProductID; return "https://demos.telerik.com/kendo-ui/service-v4/odata/Products"; } function destroyProduct(dataItem) { return "https://demos.telerik.com/kendo-ui/service-v4/odata/Products(" + dataItem.ProductID + ")"; }
-
Set up the
ODataController
:C#public class ODataWebApiWrappersProductsController : ODataController { private ODataWebApiWrappersEntities db = new ODataWebApiWrappersEntities(); // GET: odata/ODataWebApiWrappersProducts [EnableQuery] public IQueryable<ODataWebApiWrappersProduct> GetProducts() { return db.Products; } // PUT: odata/ODataWebApiWrappersProducts(5) public IHttpActionResult Put([FromODataUri] int key, ODataWebApiWrappersProduct product) { if (!ModelState.IsValid) { return BadRequest(ModelState); } if (key != product.ProductID) { return BadRequest(); } db.Products.Attach(product); db.Entry(product).State = EntityState.Modified; try { db.SaveChanges(); } catch (DbUpdateConcurrencyException) { if (!ProductExists(key)) { return NotFound(); } else { throw; } } return Updated(product); } public IHttpActionResult Post(ODataWebApiWrappersProduct product) { if (!ModelState.IsValid) { return BadRequest(ModelState); } db.Products.Add(product); //db.SaveChanges(); return Created(product); } private bool ProductExists(int key) { return db.Products.Count(e => e.ProductID == key) > 0; } }
To review the complete example, refer to the project on how to configure the Grid's DataSource to communicate with the WebAPI Controller through the OData-v4 protocol.
More ASP.NET MVC Grid Resources
- ASP.NET MVC Grid Documentation
- ASP.NET MVC Grid Demos
- ASP.NET MVC Grid Product Page
- Telerik UI for ASP.NET MVC Video Onboarding Course (Free for trial users and license holders)
- Telerik UI for ASP.NET MVC Forums