Razor Pages Grid Binding with AJAX Support

21 posts, 2 answers
  1. Eli
    Eli avatar
    28 posts
    Member since:
    Mar 2011

    Posted 25 Oct 2018 Link to this post

    I am attempting to set up a Grid in ASP.Net Core 2.1 using Razor Pages.  This grid could potentially load thousands of records so I want to only load those that I need and use ajax server side sorting/grouping etc.  I have searched around and had trouble getting this to work as I like, which is completely inside the PageModel.  Using Razor Pages it is very easy to load all the data locally, but am I correct that you can not load the data remotely Ajax style without setting it up in a separate service layer?  I can set up my own remote endpoints if needed, but am confused as to why the Grid can not treat the page handlers of the PageModel as usable endpoints as long as they return the appropriate JSON.  If it can do this, could I be pointed to a simple sample?   Thanks.

  2. Answer
    Georgi
    Admin
    Georgi avatar
    695 posts

    Posted 30 Oct 2018 Link to this post

    Hello Eli,

    I have assembled a small sample which demonstrates how to create a grid with AJAX binding in a Razor Pages project with enabled server operations. The grid requests the page handlers of the current page.

    Attached you will find the sample. Please use it as a reference.


    Regards,
    Georgi
    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.
  3. Eli
    Eli avatar
    28 posts
    Member since:
    Mar 2011

    Posted 05 Apr 2019 in reply to Georgi Link to this post

    The project that was attached worked fine and I was able to get mine to work as well with good success.  However, I found that the Grid stops working (no data) as soon as you add a Controller to the project.  It may be something simple, but I have not been able to find out why.  I am assuming that the grid begins looking to the Controllers folder for the action rather than the PageModel, I did not see how to mix the two. If you simply add a Controllers folder to the root with a TestController.cs file like below, any grid with PageModel binding fails and the read url for the grid is blank.

    namespace RazorPageGridTest.Controllers
        public class TestController : Controller
        {       
            public string Get()
            {
                return  "value1";
            }             
        }
    }
  4. Georgi
    Admin
    Georgi avatar
    695 posts

    Posted 10 Apr 2019 Link to this post

    Hello Eli,

    I have tested the same in the project from my previous message but the grid still worked as expected on my end. I assume that some routing conflict appears on your end and the framework does not request the correct handler.

    Is the page also named `Test`?


    Regards,
    Georgi
    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.
  5. Eli
    Eli avatar
    28 posts
    Member since:
    Mar 2011

    Posted 11 Apr 2019 in reply to Georgi Link to this post

    In order to reproduce failure, all I need to do is download the ajax-binding-test project from this thread, add a controllers folder and a controller underneath it by any name.

    I tried VS2017 and 2019, I tried .net core 2.1 and 2.2 and I tried multiple Telerik control versions including the latest 2019.1.220

    I also tried a second computer with a fresh install of VS.

    It is certainly a routing issue at some level.  The customers page works fine if I put in a full path of: 

    /Customer?handler=ReadRecords&action=Customer&controller=Index

     

    If it is better, I can open up a ticket and post files.  Am I able to set the Grid paths directly for Read and Update?

  6. Eli
    Eli avatar
    28 posts
    Member since:
    Mar 2011

    Posted 11 Apr 2019 in reply to Eli Link to this post

    Actually all that is needed to load the page instead of blank is to use the path

    /Customer?handler=ReadRecords

  7. Georgi
    Admin
    Georgi avatar
    695 posts

    Posted 15 Apr 2019 Link to this post

    Hi Eli,

    I assume that using the route from your last message solves the incorrect url issue. Please correct me if I am wrong.

    If that is the case, thanks for sharing your solution with the community. If further questions related to the initial one arise at any point you can use this thread to get back to us.


    Regards,
    Georgi
    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.
  8. Eli
    Eli avatar
    28 posts
    Member since:
    Mar 2011

    Posted 15 Apr 2019 in reply to Georgi Link to this post

    Sorry for the confusion, but no it is not solved.  I just meant that I am able to get the grid to load using that string, but that is not making use of AJAX and the grid still does not work as it should with AJAX Get and POST.  When you view source in the browser those properties are empty.
  9. Alex Hajigeorgieva
    Admin
    Alex Hajigeorgieva avatar
    1082 posts

    Posted 18 Apr 2019 Link to this post

    Hello, Eli,

    I was able to reproduce the routing issue which occurs when a Controller is added and I suppose that this may be expected to a certain extent since the MVC concept and the Razor pages one are not intended to be use together. Nonetheless, I then  used the direct Url which produces requests with the expected parameters sent as form data:



    Can you let me know what is that you are missing in your tests, perhaps I misunderstood the question?

    Kind Regards,
    Alex Hajigeorgieva
    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.
  10. Eli
    Eli avatar
    28 posts
    Member since:
    Mar 2011

    Posted 24 Apr 2019 in reply to Alex Hajigeorgieva Link to this post

    I do not think it is accurate to say that MVC and Razor pages are not intended to be used together.  Microsoft's own principal Core sample app and ebook mix the two freely.  https://github.com/dotnet-architecture/eShopOnWeb

    That said, my Razor Pages + Telerik has been mostly an exploration and I think it will be easier to just stick with MVC for the time being which is much more likely to work as expected and be fully documented.  The documentation and support for Razor Pages without workarounds has been lacking to date in the Telerik controls.

  11. Answer
    Georgi
    Admin
    Georgi avatar
    695 posts

    Posted 29 Apr 2019 Link to this post

    Hi Eli,

    Let me start off by saying that I totally understand your frustration and that we apologize for the caused inconvenience. Generally speaking, the Telerik components for MVC Core and Razor pages are the same - the components depend on .Net Core and both MVC Core and Razor pages are based on .Net Core. In other words, you can use the Mvc Core documentation of the components. Furthermore, I can confirm that we are currently working on extending and improving our documentation for the server wrappers.

    Regarding the Razor Pages with a controller issue. I have tested the same on my end and it seems to work as expected. For your convenience I am attaching the sample I used for testing. Could you please examine it and let me know what I am missing?

    I look forward to your reply.


    Regards,
    Georgi
    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.
  12. Eli
    Eli avatar
    28 posts
    Member since:
    Mar 2011

    Posted 29 Apr 2019 in reply to Georgi Link to this post

    It looks like the the problem is simply how the datasource is bound.  In the initial project (ajax-binding-test) it used a different way to map the handler commands and is what is shown throughout documentation (Pic #1).  In your most recently attached project the handlers are matched directly with Url which makes sense.  

    I realize the same documentation can be used that is in place for MVC and generally it does work the same and as expected.  There are just things such as this that are not clear it needs to be done a specific way for Razor Pages for someone who does not know the ins and outs of Kendo.  On the Ajax Grid binding page (https://docs.telerik.com/aspnet-core/html-helpers/data-management/grid/binding/ajax-binding)  it should reference that direct Url needs to be used for Razor pages.  Things like that would go a long way.  Sorry if that info is somewhere that I did not see.  Now that I know what needs to be done and I am able to find it on a couple forum posts.

    Thank you and I appreciate your correspondence.

  13. Eli
    Eli avatar
    28 posts
    Member since:
    Mar 2011

    Posted 29 Apr 2019 in reply to Eli Link to this post

    To be clear, using the direct Url when setting up the datasource to grid does work with controller(s) present in the attached project and mine as well.
  14. Georgi
    Admin
    Georgi avatar
    695 posts

    Posted 01 May 2019 Link to this post

    Hello Eli,

    I am happy to hear that the provided sample helped you resolve the issue.

    Just on a side note, our VS template for Razor Pages uses the same syntax for the urls. You can find more information in the following article:



    Regards,
    Georgi
    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.
  15. Web
    Web avatar
    3 posts
    Member since:
    Jun 2011

    Posted 16 Dec 2019 in reply to Georgi Link to this post

    In your example, how do I pass a parameter when using the handler ReadRecord.

    My model has the value for companyid which I need to pass to the ReadRecord 

  16. Tsvetomir
    Admin
    Tsvetomir avatar
    790 posts

    Posted 17 Dec 2019 Link to this post

    Hello,

    I have noticed that you have submitted a support thread in the private system. It is recommended to avoid submitting duplicate tickets. Nevertheless, I am sharing the provided answer in case anyone else from the community come across this scenario:

    The Kendo UI Grid data source exposes a Data() option that allows for sending additional parameters to the server-side:

    .Read(r => r.Action("Company", "Index", new { handler = "ReadRecords",  }).Data("additionalData")
    Within the JavaScript function handler return the property of the model of the page:
        function additionalData() {
             //return $.extend(true, {}, kendo.antiForgeryTokens(), {companyId: '@Model.CompanyId'});
             return {companyId: '@Model.CompanyId'};
        }
    
    Accept it on the server-side as follows:

           public JsonResult OnPostRead([DataSourceRequest] DataSourceRequest request, string companyId)
            {
                return new JsonResult(orders.ToDataSourceResult(request));
            }

    Best regards,
    Tsvetomir
    Progress Telerik

    Get quickly onboarded and successful with Telerik UI for ASP.NET Core with the dedicated Virtual Classroom technical training, available to all active customers.
  17. Web
    Web avatar
    3 posts
    Member since:
    Jun 2011

    Posted 17 Dec 2019 in reply to Tsvetomir Link to this post

    This worked. However, when I bring the data back it shows nothing in the grid

    Here is the grid control

     

    Here is the method

    public async Task<JsonResult> OnPostRead([DataSourceRequest] DataSourceRequest request ,string companyId , string primarycategory)
            {
               if( String.IsNullOrEmpty(companyId))
                   {
                    return new JsonResult(" ");
                }

                TokenResponse token = await GetToken.HandleToken();

                List<CategoryView> categorylist = await GetListCategories(token);

                List<CompanyCategory> pccat = new List<CompanyCategory>();
                pccat = await GetCategory(token, companyId, primarycategory, categorylist);

                return new JsonResult(pccat.ToDataSourceResult(request)) ;
            }

    Here is my grid

    Html.Kendo().Grid<CompanyCategory>()
                          .Name("grid")
                          .AutoBind(false)
                          .Columns(x =>
                          {
                              
                              x.Bound(c => c.category);
                              x.Bound(c => c.id);
                              x.Bound(c => c.company);
                              x.Bound(c => c.primarycategory);

                              x.Command(command => { command.Destroy(); }).Width(250);
                          })

                          .DataSource(d => d.Ajax()
                           .Read(r => r.Action("Company", "Index", new { handler = "Read" }).Data("additionalData").Type(HttpVerbs.Post))
                            .Destroy(u => u.Action("Company", "Index", new { handler = "Update" }).Data("deleteData").Type(HttpVerbs.Post))
                            .Model(m=> m.Id(id=>id))
                               //.PageSize(10)
                               )

                          )

  18. Tsvetomir
    Admin
    Tsvetomir avatar
    790 posts

    Posted 19 Dec 2019 Link to this post

    Hi,

    Passing of one parameter to the server-side could be done with the help of a plain object. However, with the introduction of the RazorPages, it is mandatory to send an anti-forgery token as well. Could you try the same approach but with the commented section of the script tag from my previous response?

        function additionalData() {
             return $.extend(true, {}, kendo.antiForgeryTokens(), {companyId: '@Model.CompanyId'});
            // return {companyId: '@Model.CompanyId'};
        }

    Also, can you check the console of the browser for any errors that might have been thrown? In case the issue persists, is it possible for you to share a sample where the faulty behavior could be reproduced, as the provided code snippets seem correct?

     

    Regards,
    Tsvetomir
    Progress Telerik

    Get quickly onboarded and successful with Telerik UI for ASP.NET Core with the dedicated Virtual Classroom technical training, available to all active customers.
  19. Web
    Web avatar
    3 posts
    Member since:
    Jun 2011

    Posted 07 Jan 2020 in reply to Georgi Link to this post

    Thank you. You can close this ticket. It works
  20. Mad
    Mad avatar
    1 posts
    Member since:
    Feb 2017

    Posted 18 Mar 2020 in reply to Georgi Link to this post

    How would the create and update methods work this way? The read method is fine - that part works for me. 

    Could you update your example to include create and update? 
  21. Georgi
    Admin
    Georgi avatar
    695 posts

    Posted 23 Mar 2020 Link to this post

    Hello Mad,

    You can find a sample which contains a grid with enabled crud operations in Razor Pages in the following repository:

    Regards,
    Georgi
    Progress Telerik

    Get quickly onboarded and successful with Telerik UI for ASP.NET Core with the dedicated Virtual Classroom technical training, available to all active customers.
Back to Top