This is a migrated thread and some comments may be shown as answers.

Populating a Kendo Grid from an ASP.NET Core Razor Page

3 Answers 352 Views
Grid
This is a migrated thread and some comments may be shown as answers.
Stuart
Top achievements
Rank 1
Stuart asked on 24 Apr 2019, 07:33 AM
I have a grid defined like this...

<div id="view">
    <div id="grid" data-role="grid"
        data-editable="false"
        data-columns="[{ 'field': 'Name' }, { 'field': 'Version'}]"
        data-bind="source: releases">
    </div>
</div>

and a view model defined so...

var viewmodel = kendo.observable({
    releases: new kendo.data.DataSource({
        schema: {
            model: {
                id: "Id",
                fields: {
                    Id: { type: "string" },
                    Name: { type: "string" },
                    Version: { type: "string" },
                    CreatedOn: { type: "datetime" }
                }
            }
        },
        transport: {
            read: {
                url: "/Release/Index?handler=List",
                type: "jsonp"
            }
        }
    })
});

 

When I try and render the page, the controls show, but there is no data, instead I get a 400 error. More reading tells me about anti-forgery tokens and how to set the header on my post request, so I add this to the top of my page....

@inject Microsoft.AspNetCore.Antiforgery.IAntiforgery Xsrf


And, I set the header for the call with the anti forgery token, with this in my client side code...

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


Now when I call my page, I get "Cannot read property 'read' of undefined."

Everything I've read suggests that I'm doing it right!

What am I not doing?

3 Answers, 1 is accepted

Sort by
0
Tsvetomir
Telerik team
answered on 26 Apr 2019, 06:52 AM
Hi Stuart,

With the introduction of the Razor Pages for the ASP.NET Core, sending anti-forgery tokens is mandatory. The Kendo UI suite already exposes a method which could be used to collect the tokens on the page. After that, send them with the request. Doing so in the beforeSend event handler is a possible approach, however, the data configuration could be used as well:

transport: {
    type:"aspnetmvc-ajax",
    read: {
        url: "/Index?handler=Read",
        data: function () {
            return kendo.antiForgeryTokens();
        },
        type:"POST"
    }

When using the anti-forgery tokens, the type of the read request has to be explicitly set to be "POST". One more thing worth mentioning is that the property which holds the data items has to be specified in the schema of the data source. If there are no additional modifications done, by default, it is called "Data":

schema: {
    model: {
        id: "OrderID",
        fields: {
            OrderID: { type: "number" },
            ShipName: { type: "string" },
            ShipCity: { type: "string" }
        }
    },
    data: 'Data'

You would decorate the page as follows:

@inject Microsoft.AspNetCore.Antiforgery.IAntiforgery Xsrf
@Html.AntiForgeryToken()

What I have noticed while investigating the provided code snippets is that the read method is called on an undefined object. You would have to call this for the grid's data source:

grid.dataSource.read();

I am attaching a sample project for your reference. Examine it and let me know in case additional assistance is required.


Kind regards,
Tsvetomir
Progress Telerik
Get quickly onboarded and successful with your Telerik and/or Kendo UI products with the Virtual Classroom free technical training, available to all active customers. Learn More.
0
Stuart
Top achievements
Rank 1
answered on 26 Apr 2019, 01:42 PM

First off, thank you.

Your solution works in all but the major sense of not displaying any data!.

In my server-side code I have ...

var x = new JsonResult(data.ToDataSourceResult(request))

When this line is called I can see, when I drill down in to 'x' that my data is there, the grid is rendered so that the <tbody> tag is empty. I have no idea what's happening.

(See ss1.png)

Now for the ear-bending, You guys have got to get you act sorted out with respect to the docs. back in the days when I was a telerik MVP there was just Telerik WebForms controls and people like Nikolay Dobrev were part of the team, your docs were second to none.

I've been trying to figure out from the odd word here and there how to fix this problem.
The result I came up with had my grid definition like this

transport: {
    read: function(options) {
        $.ajax({
            url: `/Release/Index?handler=List&filter=${$("#filter").val()}`,
            dataType: "json",
            headers: {
                "Content-Type": "application/json",
                "RequestVerificationToken": "@Xsrf.GetAndStoreTokens(HttpContext).RequestToken"
            },
            type: "POST",
            success: function(result) {
                options.success(result);
            },
            error: function(result) {
                options.error(result);
            }
        });
    }
}

 

and a post method in my page that looked like this...

public JsonResult OnPostList(string filter)
{
    var data = // Do stuff
 
    return new JsonResult(data);
}

If anything in your documentation tells the MVVM developer what they need to do, then it is really well hidden.
Now, whilst the solution I have works, I want to have it work the way that you guys, the authors say it should. consquently, I'm going to have to stick with my solution for now, but I really want you to post something that I can use that makes your solution work.

And then, please, please, please, sort out the documentation for MVVM.

 

 

0
Tsvetomir
Telerik team
answered on 30 Apr 2019, 07:37 AM
Hi Stuart,

I would really want to take the time to thank you for sharing your thoughts and experience. I do consider your feedback as valuable and it is appreciated. 

Generally, the approach that you have undertaken simply makes a jQuery ajax request to the server. The read operation, actually, internally makes an ajax request. Can you elaborate more on what do you mean by that the example provided in my previous response works but does not show any data? This is how I observe the functionality on my side:

https://screencast-o-matic.com/watch/cqfvibZpQE

Based on the provided information throughout out correspondence, I do not find anything wrong with the configuration or the server-side logic. Can you try isolating the issue in a sample project, or, probably modifying the already provided sample in order to replicate the faulty behavior? 

What I have noticed is that the type of the read operation is set to "jsonp". This type is needed only when cross-browser requests have to be made. Based on the URL that is set, I believe that the type has to be set to "POST". Moreover, setting the type of the data source's transport would help with predefininig some of the configurations:

transport: {
    type:"aspnetmvc-ajax",
    read: {
        url: "/Index?handler=Read",
        type:"POST"
    }

As a side note, can you share a sample response from the server with the returned data. A screenshot from the Network tab of the DevTools of the browser would be helpful for me as well. 

With regards to the documentation, we are constantly putting effort on improving and extending the resources we currently have. Taking the MVVM documentation section, the provided articles cover how to get started with the pattern and focus on the fundamental pillars of the MVVM. It is important to point out that the vast majority of the widgets have a live demo dedicated to the MVVM intialization and binding. Is there a specific aspect of the documentation you would like us to focus on?

I hope that these clarifications are helpful. I would be happy to assist you further in case additional questions arise.


Kind regards,
Tsvetomir
Progress Telerik
Get quickly onboarded and successful with your Telerik and/or Kendo UI products with the Virtual Classroom free technical training, available to all active customers. Learn More.
Tags
Grid
Asked by
Stuart
Top achievements
Rank 1
Answers by
Tsvetomir
Telerik team
Stuart
Top achievements
Rank 1
Share this question
or