Data Binding

All DevExtreme widgets that operate with data collections have the DataSource() method. Unlike other control methods, DataSource() do not have a direct counterpart in the DevExtreme JavaScript API, although its purpose resembles that of the Stores in the DevExtreme Data Layer. The DataSource() method configures data access for a widget. The following topics describe in details how to use this method for accessing data from different sources.

Besides DataSource(), data-bound widgets (except PivotGrid) have the DataSourceOptions() method. It exposes a builder that configures initial sorting, filtering, grouping, and other data shaping operations. The builder's methods do have JavaScript API counterparts, which are described in this section.

See Also

Static Collections

A static collection will be serialized to JSON and embedded into the widget configuration.

Razor C#
Razor VB
@(Html.DevExtreme().SelectBox()
    .DataSource(new[] { "red", "green", "blue" })
)
@(Html.DevExtreme().SelectBox() _
    .DataSource({ "red", "green", "blue" })
)

View Demo

ASP.NET MVC and Web API Controllers

Access to MVC controllers in an MVC 3, 4, 5 and .NET Core MVC app is configured alike - using the Mvc() method the DataSource()'s lambda parameter exposes. The following example shows the DataGrid widget accessing a GridDataController whose actions (GetOrders, InsertOrder, UpdateOrder, and DeleteOrder) implement CRUD operations:

Razor C#
Razor VB
@(Html.DevExtreme().DataGrid()
    .DataSource(ds => ds
        .Mvc()
        .Controller("GridData")
        .Key("OrderID")
        .LoadAction("GetOrders")
        .InsertAction("InsertOrder")
        .UpdateAction("UpdateOrder")
        .DeleteAction("DeleteOrder")
    )
)
@(Html.DevExtreme().DataGrid() _
    .DataSource(Function(ds)
        Return ds.Mvc() _
                 .Controller("GridData") _
                 .Key("OrderID") _
                 .LoadAction("GetOrders") _
                 .InsertAction("InsertOrder") _
                 .UpdateAction("UpdateOrder") _
                 .DeleteAction("DeleteOrder")
    End Function)
)

The code below details the GridDataController. CRUD operations are performed on the Northwind database's "Orders" collection. Note the use of DevExtreme.AspNet.Data, a library that facilitates writing a controller for DevExtreme ASP.NET MVC Controls.

MVC 3, 4, 5 Controller
C#
VB
using System;
using System.Linq;
using System.Net;
using System.Web.Mvc;
using DevExtreme.AspNet.Data;
using DevExtreme.AspNet.Mvc;
using Newtonsoft.Json;
using ProjectName.Models;

namespace ProjectName.Controllers {

    public class GridDataController : Controller {
        NorthwindContext _nwind = new NorthwindContext();
        const string ValidationErrorMessage = "The record cannot be saved due to a validation error";

        // Fetching items from the "Orders" collection
        public ActionResult GetOrders(DataSourceLoadOptions loadOptions) {
            var result = DataSourceLoader.Load(_nwind.Orders, loadOptions);
            var resultJson = JsonConvert.SerializeObject(result);
            return Content(resultJson, "application/json");
        }

        // Inserting a new item into the "Orders" collection
        public ActionResult InsertOrder(string values) {
            var newOrder = new Order();                             // Creating a new item
            JsonConvert.PopulateObject(values, newOrder);           // Populating the item with the values
            if (!TryValidateModel(newOrder))                        // Validating the item
                return new HttpStatusCodeResult(HttpStatusCode.BadRequest, ValidationErrorMessage);
            _nwind.Orders.Add(newOrder);                            // Adding the item to the database
            _nwind.SaveChanges();
            return new HttpStatusCodeResult(HttpStatusCode.OK);
        }

        // Updating an item in the "Orders" collection
        public ActionResult UpdateOrder(int key, string values) {
            var order = _nwind.Orders.First(o => o.OrderID == key); // Finding the item to be updated by key
            JsonConvert.PopulateObject(values, order);              // Populating the found item with the changed values
            if (!TryValidateModel(order))                           // Validating the updated item
                return new HttpStatusCodeResult(HttpStatusCode.BadRequest, ValidationErrorMessage);
            _nwind.SaveChanges();
            return new HttpStatusCodeResult(HttpStatusCode.Created);
        }

        // Removing an item from the "Orders" collection
        public void DeleteOrder(int key) {
            var order = _nwind.Orders.First(o => o.OrderID == key); // Finding the item to be removed by key
            _nwind.Orders.Remove(order);                            // Removing the found item
            _nwind.SaveChanges();
        }
    }
}
Imports System.Linq
Imports System.Net
Imports DevExtreme.AspNet.Data
Imports DevExtreme.AspNet.Mvc
Imports Newtonsoft.Json
Imports ProjectName.Models

Namespace Controllers
    Public Class OrdersController
        Inherits Controller

        Dim _nwind As New NorthwindContext()
        Const ValidationErrorMessage As String = "The record cannot be saved due to a validation error"

        ' Fetching items from the "Orders" collection
        Public Function GetOrders(ByVal loadOptions As DataSourceLoadOptions) As ActionResult
            Dim result = DataSourceLoader.Load(_nwind.Orders, loadOptions);
            Dim resultJson = JsonConvert.SerializeObject(result);
            Return Content(resultJson, "application/json")
        End Function

        ' Inserting a new item into the "Orders" collection
        Public Function InsertOrder(ByVal values As String) As ActionResult
            Dim newOrder As New Order()                     ' Creating the a item
            JsonConvert.PopulateObject(values, newOrder)    ' Populating the item with values
            If TryValidateModel(newOrder) = False Then      ' Validating the item
                Return New HttpStatusCodeResult(HttpStatusCode.BadRequest, ValidationErrorMessage)
            End If
            _nwind.Orders.Add(newOrder)                     ' Adding the item to the database
            _nwind.SaveChanges()
            Return New HttpStatusCodeResult(HttpStatusCode.Created)
        End Function

        ' Updating an item in the "Orders" collection
        Public Function UpdateOrder(ByVal key As Integer, ByVal values As String) As ActionResult
            Dim order = _nwind.Orders.First(Function(o)     ' Finding the item to be updated by key
                                               Return o.OrderID = key
                                           End Function)
            JsonConvert.PopulateObject(values, order)       ' Populating the found item with the changed values
            If TryValidateModel(order) = False Then         ' Validating the updated item
                Return New HttpStatusCodeResult(HttpStatusCode.BadRequest, ValidationErrorMessage)
            End If
            _nwind.SaveChanges()
            Return New HttpStatusCodeResult(HttpStatusCode.OK)
        End Function

        ' Removing an item from the "Orders" collection
        Public Sub DeleteOrder(ByVal key As Integer)
            Dim order = _nwind.Orders.First(Function(o)     ' Finding the item to be removed by key
                                               Return o.OrderID = key
                                           End Function)
            _nwind.Orders.Remove(order)                     ' Removing the found item
            _nwind.SaveChanges()
        End Sub
    End Class
End Namespace
.NET Core MVC Controller
C#
using System;
using System.Linq;
using Microsoft.AspNetCore.Mvc;
using DevExtreme.AspNet.Data;
using DevExtreme.AspNet.Mvc;
using Newtonsoft.Json;
using ProjectName.Models;

namespace ProjectName.Controllers {

    public class GridDataController : Controller {
        NorthwindContext _nwind;

        public OrdersController(NorthwindContext nwind) {
            _nwind = nwind;
        }

        const string ValidationErrorMessage = "The record cannot be saved due to a validation error";

        // Fetching items from the "Orders" collection
        public object GetOrders(DataSourceLoadOptions loadOptions) {
            return DataSourceLoader.Load(_nwind.Orders, loadOptions);
        }

        // Inserting a new item into the "Orders" collection
        public IActionResult InsertOrder(string values) {
            var newOrder = new Order();                             // Creating the new item
            JsonConvert.PopulateObject(values, newOrder);           // Populating the item with values
            if (!TryValidateModel(newOrder))                        // Validating the item
                return BadRequest(ValidationErrorMessage);
            _nwind.Orders.Add(newOrder);                            // Adding the item to the database
            _nwind.SaveChanges();
            return Ok();
        }

        // Updating an item in the "Orders" collection
        public IActionResult UpdateOrder(int key, string values) {
            var order = _nwind.Orders.First(o => o.OrderID == key); // Finding the item to be updated by key
            JsonConvert.PopulateObject(values, order);              // Populating the found item with the changed values
            if (!TryValidateModel(order))                           // Validating the updated item
                return BadRequest(ValidationErrorMessage);
            _nwind.SaveChanges();
            return Ok();
        }

        // Removing an item from the "Orders" collection
        public void DeleteOrder(int key) {
            var order = _nwind.Orders.First(o => o.OrderID == key); // Finding the item to be removed by key
            _nwind.Orders.Remove(order);                            // Removing the found item
            _nwind.SaveChanges();
        }
    }
}

If you use a Web API controller in your app, configure access to it using the WebApi() method of the DataSource()'s lambda parameter. The WebApi() exposes the same methods as Mvc() for specifying the controller and action names, but with one addition: You can pass true to the UpdateAction, InsertAction, and DeleteAction methods if the actions are called Get, Put, Post, and Delete. The WebApi() method is not intended for .NET Core MVC apps.

Razor C#
Razor VB
@(Html.DevExtreme().DataGrid()
    .DataSource(ds => ds
        .WebApi()
        .Controller("GridDataWebApi")
        .Key("OrderID")
        .UpdateAction(true)
        .InsertAction(true)
        .DeleteAction(true)
    )
)
@(Html.DevExtreme().DataGrid() _
    .DataSource(Function(ds)
        Return ds.WebApi() _
                 .Controller("GridDataWebApi") _
                 .Key("OrderID") _
                 .UpdateAction(true) _
                 .InsertAction(true) _
                 .DeleteAction(true)
    End Function)
)

The controller looks like this:

Web API Controller
C#
VB
using System;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Web.Http;
using DevExtreme.AspNet.Data;
using DevExtreme.AspNet.Mvc;
using System.Net.Http.Formatting;
using Newtonsoft.Json;
using ProjectName.Models;

namespace ProjectName.Controllers {

    public class GridDataWebApiController : ApiController {
        NorthwindContext _nwind = new NorthwindContext();
        const string ValidationErrorMessage = "The record cannot be saved due to a validation error";

        [HttpGet] // Fetching items from the "Orders" collection
        public HttpResponseMessage Get(DataSourceLoadOptions loadOptions) {
            return Request.CreateResponse(DataSourceLoader.Load(_nwind.Orders, loadOptions));
        }

        [HttpPost] // Inserting a new item into the "Orders" collection
        public HttpResponseMessage Post(FormDataCollection form) {
            var values = form.Get("values");                        // Getting JSON-formatted values for the new item
            var newOrder = new Order();                             // Creating the new item
            JsonConvert.PopulateObject(values, newOrder);           // Populating the item with values
            Validate(newOrder);                                     // Validating the item
            if(!ModelState.IsValid)
                return Request.CreateErrorResponse(HttpStatusCode.BadRequest, ValidationErrorMessage);
            _nwind.Orders.Add(newOrder);                            // Adding the item to the database
            _nwind.SaveChanges();
            return Request.CreateResponse(HttpStatusCode.Created);
        }

        [HttpPut] // Updating an item in the "Orders" collection
        public HttpResponseMessage Put(FormDataCollection form) {
            var key = Convert.ToInt32(form.Get("key"));             // Getting the key of the item to be updated
            var values = form.Get("values");                        // and changed values for this item
            var order = _nwind.Orders.First(o => o.OrderID == key);  // Finding the item to be updated by key
            JsonConvert.PopulateObject(values, order);              // Populating the found item with the changed values
            Validate(order);                                        // Validating the updated item
            if(!ModelState.IsValid)
                return Request.CreateErrorResponse(HttpStatusCode.BadRequest, ValidationErrorMessage);
            _nwind.SaveChanges();
            return Request.CreateResponse(HttpStatusCode.OK);
        }

        [HttpDelete] // Removing an item from the "Orders" collection
        public void Delete(FormDataCollection form) {
            var key = Convert.ToInt32(form.Get("key"));             // Getting the key of the item to be removed
            var order = _nwind.Orders.First(o => o.OrderID == key);  // Finding the item to be removed by key
            _nwind.Orders.Remove(order);                            // Removing the found item
            _nwind.SaveChanges();
        }
    }
}
Imports System.Linq
Imports System.Net
Imports System.Net.Http
Imports System.Web.Http
Imports DevExtreme.AspNet.Data
Imports DevExtreme.AspNet.Mvc
Imports System.Net.Http.Formatting
Imports Newtonsoft.Json
Imports ProjectName.Models

Namespace Controllers
    Public Class GridDataWebApiController
        Inherits ApiController

        Dim _nwind As New NorthwindContext()
        Const ValidationErrorMessage As String = "The record cannot be saved due to a validation error"

        <HttpGet> ' Fetching items from the "Orders" collection
        Public Function [Get](ByVal loadOptions As DataSourceLoadOptions) As HttpResponseMessage
            Return Request.CreateResponse(DataSourceLoader.Load(_nwind.Orders, loadOptions))
        End Function

        <HttpPost> ' Inserting a new item into the "Orders" collection
        Public Function [Post](ByVal form As FormDataCollection) As HttpResponseMessage
            Dim values = form.Get("values")                 ' Getting JSON-formatted values for the new item
            Dim newOrder As New Order()                     ' Creating the new item
            JsonConvert.PopulateObject(values, newOrder)    ' Populating the item with values
            Validate(newOrder)                              ' Validating the item
            If ModelState.IsValid = False Then
                Return Request.CreateErrorResponse(HttpStatusCode.BadRequest, ValidationErrorMessage)
            End If
            _nwind.Orders.Add(newOrder)                     ' Adding the item to the database
            _nwind.SaveChanges()
            Return Request.CreateResponse(HttpStatusCode.Created)
        End Function

        <HttpPut> ' Updating an item in the "Orders" collection
        Public Function [Put](ByVal form As FormDataCollection) As HttpResponseMessage
            Dim key = Convert.ToInt32(form.Get("key"))      ' Getting the key of the item to be updated
            Dim values = form.Get("values")                 ' and changed values for this item
            Dim order = _nwind.Orders.First(Function(o)     ' Finding the item to be updated by key
                                               Return o.OrderID = key
                                           End Function)
            JsonConvert.PopulateObject(values, order)       ' Populating the found item with the changed values
            Validate(order)                                 ' Validating the updated item
            If ModelState.IsValid = False Then
                Return Request.CreateErrorResponse(HttpStatusCode.BadRequest, ValidationErrorMessage)
            End If
            _nwind.SaveChanges()
            Return Request.CreateResponse(HttpStatusCode.OK)
        End Function

        <HttpDelete> ' Removing an item from the "Orders" collection
        Public Sub [Delete](ByVal form As FormDataCollection)
            Dim key = Convert.ToInt32(form.Get("key"))      ' Getting the key of the item to be removed
            Dim order = _nwind.Orders.First(Function(o)     ' Finding the item to be removed by key
                                               Return o.OrderID = key
                                           End Function)
            _nwind.Orders.Remove(order)                     ' Removing the found item
            _nwind.SaveChanges()
        End Sub
    End Class
End Namespace

View Demo

Controller on a Different Site

Previous examples show use-cases in which a control is on the same site as the data it accesses, and routing helps find the right controller and actions. If the data is on a different site, you can use the URL to access it via the RemoteController() method of the DataSource()'s lambda parameter. This method opens a chain whose members mirror the client-side method fields in the already familiar DevExtreme.AspNet.Data library.

Razor C#
Razor VB
@(Html.DevExtreme().DataGrid()
    .DataSource(ds => ds
        .RemoteController()
        .Key("OrderID")
        .LoadUrl("http://www.example.com/Orders/GetOrders")
        .InsertUrl("http://www.example.com/Orders/InsertOrder")
        .UpdateUrl("http://www.example.com/Orders/UpdateOrder")
        .DeleteUrl("http://www.example.com/Orders/DeleteOrder")
    )
)
@(Html.DevExtreme().DataGrid() _
    .DataSource(Function(ds)
        Return ds.RemoteController() _
                 .Key("OrderID") _
                 .LoadUrl("http://www.example.com/Orders/GetAllOrders") _
                 .InsertUrl("http://www.example.com/Orders/InsertOrder") _
                 .UpdateUrl("http://www.example.com/Orders/UpdateOrder") _
                 .DeleteUrl("http://www.example.com/Orders/DeleteOrder")
    End Function)
)

Controller in a Different Area

In an app organized into areas, a control from a view belonging to one area may need to access a data controller belonging to another. Use the Area() method to specify the data controller's area in this case.

Razor C#
Razor VB
@(Html.DevExtreme().DataGrid()
    .DataSource(ds => ds
        .Mvc()
        .Area("DifferentArea")
        // ...
    )
)
@(Html.DevExtreme().DataGrid() _
    .DataSource(Function(ds)
        Return ds.Mvc() _
                 .Area("DifferentArea") _
                 ' ...
    End Function)
)

Read-Only Data in JSON Format

A server-side control can access JSON data returned from a resource by an AJAX request. For this purpose, the lambda parameter of the DataSource() method exposes the StaticJson() method. It opens a chain of methods configuring access to JSON data.

Razor C#
Razor VB
@(Html.DevExtreme().SelectBox()
    .DataSource(ds => ds
        .StaticJson()
        .Url("http://www.example.com/dataservices/jsondata")
        .Key("ID")
        .CacheAllData(true) // loads all data at once and saves it in cache; true by default
    )
)
@(Html.DevExtreme().SelectBox() _
    .DataSource(Function(ds)
        Return ds.StaticJson() _
               .Url("http://www.example.com/dataservices/jsondata") _
               .Key("ID") _
               .CacheAllData(True) ' loads all data at once and saves it in cache; true by default
    End Function)
)

Besides accepting absolute URLs, which is shown in the previous code, the Url() method can accept virtual paths.

Razor C#
Razor VB
@(Html.DevExtreme().SelectBox()
    .DataSource(ds => ds
        .StaticJson()
        .Url(@Url.Content("~/dataservices/jsondata"))
    )
)
@(Html.DevExtreme().SelectBox() _
    .DataSource(Function(ds)
        Return ds.StaticJson() _
               .Url(Url.Content("~/dataservices/jsondata"))
    End Function)
)

You can also use a JSONP callback parameter supported by jQuery.ajax().

Razor C#
Razor VB
@(Html.DevExtreme().SelectBox()
    .DataSource(ds => ds
        .StaticJson()
        .Url("http://www.example.com/dataservices/jsonpdata?callback=?")
    )
)
@(Html.DevExtreme().SelectBox() _
    .DataSource(Function(ds)
        Return ds.StaticJson() _
               .Url("http://www.example.com/dataservices/jsonpdata?callback=?")
    End Function)
)

In addition, the DataSource() method has several overloads for configuring access to JSON data more briefly. Using them, you can specify the URL to data...

Razor C#
Razor VB
@(Html.DevExtreme().SelectBox()
    .DataSource("http://www.example.com/dataservices/jsondata")
)
@(Html.DevExtreme().SelectBox() _
    .DataSource("http://www.example.com/dataservices/jsondata")
)

... or the URL and the key field.

Razor C#
Razor VB
@(Html.DevExtreme().SelectBox()
    .DataSource("http://www.example.com/dataservices/jsondata", "ID")
)
@(Html.DevExtreme().SelectBox() _
    .DataSource("http://www.example.com/dataservices/jsondata", "ID")
)

OData

Also, DevExtreme ASP.NET MVC Controls operate with an OData service out of the box. To address an OData service, call the DataSource() method and pass a lambda expression to it. The lambda parameter exposes the OData() method that configures access to the OData service.

Razor C#
Razor VB
@(Html.DevExtreme().DataGrid()
    .DataSource(ds => ds
        .OData()
        .Version(4)
        .Url("http://services.odata.org/V4/Northwind/Northwind.svc/Products")
        .JSONP(true)
        .Key("ProductID")
        .Expand("Category")
    )
)
@(Html.DevExtreme().DataGrid() _
    .DataSource(Function(ds)
        Return ds.OData() _
                 .Version(4) _
                 .Url("http://services.odata.org/V4/Northwind/Northwind.svc/Products") _
                 .JSONP(True) _
                 .Key("ProductID") _
                 .Expand("Category")
    End Function)
)

View Demo

OLAP Cube

An OLAP cube is a multi-dimensional dataset that allows for data mining and analysis. For displaying data from an OLAP cube, DevExtreme provides the PivotGrid widget. You can access the OLAP cube by calling the DataSource() method as shown in the following code. The lambda expression passed to this method configures the XmlaStore data store.

Razor C#
Razor VB
@(Html.DevExtreme().PivotGrid()
    .DataSource(ds => ds
        .Store(s => s.Xmla()
            .Url("http://my-web-srv01/OLAP/msmdpump.dll")
            .Catalog("AdventureWorksDW2012")
            .Cube("Adventure Works")
        )
    )
)
@(Html.DevExtreme().PivotGrid() _
    .DataSource(Function(ds)
        Return ds.Store(Function(s)
            Return s.Xmla() _
                    .Url("http://my-web-srv01/OLAP/msmdpump.dll") _
                    .Catalog("AdventureWorksDW2012") _
                    .Cube("Adventure Works")
        End Function)
    End Function)
)

View Demo