简体   繁体   中英

Setting Kendo UI Grid DataSource Read property with Handler in ASP.NET Core MVC with Razor Pages

I am using the Kendo UI for ASP.NET Core MVC suite with a Razor Pages web application so I am trying to use the handler technique for the grid's server operations.

@(Html.Kendo().Grid<CustomerViewModel>()
        .Name("CustomersGrid")
        .Columns(columns =>
        {
            columns.Bound(x => x.CustomerId).Title("Student ID");
            columns.Bound(x => x.CustomerName).Title("Name");
        })
        .Pageable()
        .Sortable()
        .DataSource(dataSource => dataSource
            .Ajax()
            .PageSize(20)
            .ServerOperation(true)
            .Read(read => read.Url("/Customers?handler=Read")))
         )

I looked in the network tab and it is making the correct POST to http://localhost:5000/Customers?handler=Read however I am not ending up at my breakpoint and I get a status code 400.

In the razor page's code behind the Action method is named OnPostReadAsync

Any idea why this is not working? In addition to .Url also tried using read.Action and read.Route in the .Read property of the DataSource.

Here is the class with the action method:

public class IndexModel : PageModel
{
    private readonly ICustomerRepository _customerRepository;
    private readonly IMapper _mapper;

    public IndexModel(ICustomerRepository customerRepository, IMapper mapper)
    {
        _customerRepository = customerRepository;
        _mapper = mapper;
    }

    public IList<CustomerViewModel> Customers { get; set; }

    public async Task<IActionResult> OnPostReadAsync([DataSourceRequest] DataSourceRequest request)
    {
        // THIS IS WHERE I WANT IT TO GO FOR READ

        var customersFromDb = await _customerRepository.FilterAsync();
        return new JsonResult(_mapper.Map<IList<Customer>, IList<CustomerViewModel>>(customersFromDb).ToDataSourceResult(request));
    }
}

You may be doing this already, but I didn't see it in your code. Remember the Razor Pages require the anti-forgery token. You can inject it into your markup like this:

@inject Microsoft.AspNetCore.Antiforgery.IAntiforgery Xsrf

And I added this function to set it on the grid's dataSource requests:

$(function () {
    const requestVerificationToken = '@Xsrf.GetAndStoreTokens(HttpContext).RequestToken';
    const beforeSend = req => req.setRequestHeader('RequestVerificationToken', requestVerificationToken);
    const grid = $("#grid").getKendoGrid();
    grid.dataSource.transport.options.create.beforeSend = beforeSend;
    grid.dataSource.transport.options.update.beforeSend = beforeSend;
    grid.dataSource.transport.options.destroy.beforeSend = beforeSend;
});

Without that token all the PageModel custom handlers will return 400 errors.

Reference: Prevent Cross-Site Request Forgery (XSRF/CSRF) attacks in ASP.NET Core

To me, using a POST to get data is wrong. If you want to use a GET, then append .Type(HttpVerbs.Get) to your Read method:

.DataSource(data =>
{
    data.Ajax()
      .Events(events => events.Error("grid_error"))
      .Read(read => read.Url("./Groups?handler=Read").Type(HttpVerbs.Get));
      //.Sort(sort => sort.Add("Name").Ascending())
      //.PageSize(20);
})

And keep your usual Ajax method but the convention expects OnGet plus the value specified by handler=...

public IActionResult OnGetRead([DataSourceRequest] DataSourceRequest request)
{
    var result = db.Queryable<IdentityRole>();
    return new JsonResult(result.ToDataSourceResult(request));
}

The TagHelper style is similar:

<datasource type="DataSourceTagHelperType.Ajax" custom-type="AndyB.Identity.IdentityRole">
  <transport>
    <read url="./Groups?handler=Read" type="Get" />
  </transport>
  <sorts>
    <sort field="Name" direction="ascending" />
  </sorts>
</datasource>

Don't use for inserts, updates or delete, continue to use the POST

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM