Razor Page Handlers
- 3 minutes to read
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:
- They are native for APIs.
- API controllers can be generated with the DevExtreme Scaffolder, while page handlers need to be created in code.
Implement Razor Page Handlers
Razor page handlers are similar to API controller actions, but have several specific differences:
A handler name
Handler methods are executed as a result of a HTTP request. They are named according to the scheme:
On[HttpMethod][HandlerName]Async
. TheAsync
suffix is optional, and is used for asynchronous functions.Examples:
OnGetMyHandler()
is used to process the GET request,OnPostMyHandler()
- to process the POST request, etc.Refer to Microsoft documentation for more information about handlers.
A handler body
Page handlers contain the same operations that you use in controller actions. There may be instances when you may need to use other methods to perform these operations (for instance, you may utilize
new JsonResult()
(in Razor page handlers) instead ofJson()
(in controller actions)).Antiforgery validation
Razor pages are automatically protected from XSRF/CSRF. When you bind a control to page handlers, you need to pass an antiforgery token to the DataSource.OnBeforeSend method (see Configure Access to Page Handlers).
The following code illustrates a typical page model for the DataGrid control. The model has two handler methods:
OnGetGridData()
- runs on theGET
request, provides data for the DataGrid.OnPutGridRow()
- runs on thePUT
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"]);
}
}
}
}
Configure Access to Page Handlers
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)
)
)