aspnetcore-401221-devextreme-based-controls-concepts-bind-controls-to-data-razor-page-handlers.md
This topic describes how to bind DevExtreme-based controls to Razor page handlers.
Note
It is recommended that you bind the controls to API controllers because:
Razor page handlers are similar to API controller actions, but have several specific differences:
A handler name
A handler body
Antiforgery validation
The following code illustrates a typical page model for the DataGrid control. The model has two handler methods:
OnGetGridData() - runs on the GET request, provides data for the DataGrid.
OnPutGridRow() - runs on the PUT request, updates a DataGrid’s row.
CRUD operations are performed on the Northwind database’s Categories collection.
using DevExtreme.AspNet.Data;
using DevExtreme.AspNet.Mvc;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;
using Newtonsoft.Json;
using System;
using System.Collections;
using System.Linq;
namespace MyApp.Pages {
public class MyPageModel : PageModel {
readonly NorthwindContext _context;
public MyPageModel(NorthwindContext context) {
_context = context;
}
// runs on the GET request
public IActionResult OnGetGridData(DataSourceLoadOptions loadOptions) {
var categories = _context.Categories.Select(i => new {
i.CategoryId,
i.CategoryName
});
return new JsonResult(DataSourceLoader.Load(categories, loadOptions));
}
// runs on the PUT request
public IActionResult OnPutGridRow(int key, string values) {
var model = _context.Categories.FirstOrDefault(item => item.CategoryId == key);
var _values = JsonConvert.DeserializeObject<IDictionary>(values);
PopulateModel(model, _values);
if(!TryValidateModel(model))
return BadRequest("Validation failed");
_context.SaveChanges();
return new OkResult();
}
// a handler for the POST request
//...
// a handler for the DELETE request
//...
void PopulateModel(Category model, IDictionary values) {
if(values.Contains("CategoryName")) {
model.CategoryName = Convert.ToString(values["CategoryName"]);
}
}
}
}
Use the DataSourceFactory.RemoteController method to configure access to data.
This method opens a chain of methods, including methods for CRUD operations: InsertUrl(), LoadUrl(), UpdateUrl(), DeleteUrl(). These CRUD methods take a URL for a Razor page handler. You can obtain this URL using Url.Page(), where you specify a page name and a page handler name defined in a page model.
The following example shows how to bind the DataGrid to page handlers. The LoadUrl() and UpdateUrl() methods provide access to the OnGetGridData() and OnPutGridRow() handler methods.
@page
@model MyApp.Pages.MyPageModel
@inject Microsoft.AspNetCore.Antiforgery.IAntiforgery Xsrf
<script>
function grid_dataSource_beforeSend(op, ajax) {
ajax.headers = {
RequestVerificationToken: "@Xsrf.GetAndStoreTokens(Model.HttpContext).RequestToken"
};
}
</script>
@(Html.DevExtreme().DataGrid<Category>()
.DataSource(ds => ds.RemoteController()
.LoadUrl(Url.Page(null, "GridData")) // access to the GridData handler defined in the OnGetGridData method in the page model
.UpdateUrl(Url.Page(null, "GridRow")) // access to the GridRow handler defined in the OnPutGridRow method in the page model
.Key("CategoryId")
.OnBeforeSend("grid_dataSource_beforeSend") // passes an antiforgery token
)
.RemoteOperations(true)
.Columns(columns => {
columns.AddFor(m => m.CategoryName);
})
.Editing(e => e
.AllowUpdating(true)
//.AllowAdding(true)
//.AllowDeleting(true)
)
)