dataSource transport function mode read and wrong request parameters

10 posts, 1 answers
  1. Claudio
    Claudio avatar
    21 posts
    Member since:
    Feb 2015

    Posted 17 Feb 2015 Link to this post

    Hi, i use kendo ui grid (for asp.net mvc)  without problem if i declare dataSource transport read as url like:

    var dataSource = {
       pageSize: 20,
       batch: true,
       serverOperation: true,
       serverPaging: true,
       serverSorting: true,
       serverFiltering: true,
       type: "aspnetmvc-ajax",
       read:
       {
          url: '/Home/GetNodes',
          type: "POST",
          dataType: "json",
          data: function ()
          {
             return {'p1': 'some text', 'p2': 'other'}
          }
       }
    };

    now the problem is that i want do use function mode read (is a software design requirement)
    but the sintax used to pass request parameters to server differ from use transport type "aspnetmvc-ajax" or not.
    if i set transport type "aspnetmvc-ajax" the read function is not fired, 
    but if not set transport type "aspnetmvc-ajax" the request parameter is not passed well on server side!

    if i watch the post parameters sent via http:

    with transport type "aspnetmvc-ajax":

    page:1
    pageSize:20
    sort:Field1-asc
    filter:Field1~eq~'value1'

    without transport type "aspnetmvc-ajax":
    page:1
    pageSize:20
    sort:[{field:Field1, dir:asc}]
    filter:{filters:[{operator:eq, value:value1, field:Field1}], logic:and}

    sort and filter value parameters differ from "aspnetmvc-ajax" version and server-side are null!

    as workaround i manually parse the request params inside parameterMap as shown on bottom, 
    translating sort and filter value sintax compliance with "aspnetmvc-ajax" version and server side are passed well.

    - there is a best solution? 
    - why if i use "aspnetmvc-ajax" transport type the read function is not invoked?
    - if the only solution to use read function is to avoid using "aspnetmvc-ajax" transport type,
      there is a standard way to format request parameters for use on server side in DataSourceRequest object?

    thanks

     attually my workaround is:

    var dataSource = {
       pageSize: 20,
       batch: true,
       serverOperation: true,
       serverPaging: true,
       serverSorting: true,
       serverFiltering: true,
       read: function (options)
       {
          var request = $scope.grdDocuments.dataSource.transport.parameterMap({
              filter: $scope.grdDocuments.dataSource.filter(),
              group: $scope.grdDocuments.dataSource.group(),
              sort: $scope.grdDocuments.dataSource.sort(),
              page: $scope.grdDocuments.dataSource.page(),
              pageSize: $scope.grdDocuments.dataSource.pageSize()
          });
          
          httpService.GetNodes(request.filter, request.group, request.sort, request.page, request.pageSize, sFolderId, ... other parameters)
          .then(
          function (args)
          {
              //Verifica esito della richiesta http
              if (!sharedService.CheckHttpRequestResult(args, 'GetNodes'))
              {
                  options.error(null);
                  return;
              }

              options.success(args.data);
          }
          );
       },
       parameterMap: function (data, operation)
       {
          //Trasformazione parametro filter
          if (typeof data.filter !== 'undefined')
          {
             //normale: {filters:[{operator:eq, value:a, field:Affidatario}], logic:and}
             //trasformato: Affidatario~eq~'a'
             var filter = '';
             for (var i = 0; i < data.filter.filters.length; i++)
             {
                if (filter !== '')
                   filter += '~' + data.filter.logic + '~';

                var fieldValue = "'" + data.filter.filters[i].value + "'";

                //Formattazione valore in base al formato della colonna
                var found = model.fields[data.filter.filters[i].field];
                if (typeof found !== 'undefined')
                {
                   if (found.type === 'number')
                      fieldValue = data.filter.filters[i].value;
                   else if (found.type === 'date')
                      fieldValue = "datetime'" + data.filter.filters[i].value.format('Y-m-d') + "T00-00-00'";
                }

                filter += data.filter.filters[i].field + '~' + data.filter.filters[i].operator + '~' + fieldValue;
             }
             data.filter = filter;
          }

          //Trasformazione parametro sort
          if (typeof data.sort !== 'undefined')
          {
             //normale: [{field:Anno, dir:asc}]
             //trasformato: Anno-asc
             var sort = '';
             for (var i = 0; i < data.sort.length; i++)
             {
                if (sort !== '')
                   sort += '~';

                sort += data.sort[i].field + '-' + data.sort[i].dir;
             }
             data.sort = sort;
          }

          var result = JSON.parse(JSON.stringify(data));
          return result;
       }
    };

    server side:

    public JsonResult GetNodes([DataSourceRequest]DataSourceRequest request, string sFolderId, ... other parameters)
    {

    }
  2. Rosen
    Admin
    Rosen avatar
    3253 posts

    Posted 19 Feb 2015 Link to this post

    Hello Claudio,

    As you may know when setting given transport type, the DataSource will instantiate a specific transport object. This type usually is implementing communication for specific server technology.
    When you use custom transport - by implementing read, you will bypass the transport or giving the transport type set(as with the aspnetmvc), the transport will not use the read function. Also you should be aware that the aspnetmvc transports are designed to be used internally by the ASP.NET MVC wrappers and not as stand-alone. Mixing them with the plain JavaScript initialization and applying customizations can be tricky.

    So, to your questions:

    The aspnetmvc-ajax does not support injecting custom read function. If you want custom transport you will need to skip setting the transport type. Also the parameterMap is executed only for built-in transports, thus you will need to manually format the parameters in the correct format prior to sending them the server. However, it is possible to call the built-in aspnetmvc-ajax parameterMap if same formatting is required. For instance in the code snippet you have provided can be changes similar to the following:

    read: function (options)
    {
       var request = kendo.data.transports["aspnetmvc-ajax"].fn.options.parameterMap(options.data, "read", false);
      //.....

    I have noticed that in the snippet you have pasted, the read function is not declared correctly. It should be under the transport and not a direct child of the dataSource settings.

    Regards,
    Rosen
    Telerik
     

    Check out the Telerik Platform - the only platform that combines a rich set of UI tools with powerful cloud services to develop web, hybrid and native mobile apps.

     
  3. Claudio
    Claudio avatar
    21 posts
    Member since:
    Feb 2015

    Posted 11 May 2015 in reply to Rosen Link to this post

    Hi, i tested your workaround calling kendo.data.transports["aspnetmvc-ajax"].fn.options.parameterMap(options.data, "read",false);

     but calling this function throw an exception, and watching inside parameterMap function the problem is that member this.options is undefined.

     how to solve?

    Thanks

  4. Claudio
    Claudio avatar
    21 posts
    Member since:
    Feb 2015

    Posted 11 May 2015 in reply to Claudio Link to this post

    in particular the parameterMap function try to access to this.options.prefix member but this.options is undefined
  5. Answer
    Rosen
    Admin
    Rosen avatar
    3253 posts

    Posted 12 May 2015 Link to this post

    Hello Claudio,

    The error is caused by the fact that this parameterMap is designed for different transport type. However, you could workaround this error by defining an options.prefix  and call the parameterMap if the correct context:

                           read: function(options) {                              
                                   this.options = { prefix: "" };
                                    var data = kendo.data.transports["aspnetmvc-ajax"].prototype.options.parameterMap.call(this, options.data, "read", false);
                            }

    Regards,
    Rosen
    Telerik
     

    See What's Next in App Development. Register for TelerikNEXT.

     
  6. Claudio
    Claudio avatar
    21 posts
    Member since:
    Feb 2015

    Posted 12 May 2015 in reply to Rosen Link to this post

    ok thanks!
  7. Sam
    Sam avatar
    34 posts
    Member since:
    Dec 2016

    Posted 27 Oct 2017 Link to this post

    Is there any plan to fully support `aspnetmvc-ajax` on the client side ?

    The above solution only works for parameters, and not aggregates etc.

  8. Stefan
    Admin
    Stefan avatar
    2880 posts

    Posted 31 Oct 2017 Link to this post

    Hello, Sam,

    Currently, there are no short or mid-term plans to fully support the "aspnetmvc-ajax"  type for the jQuery widgets working on the client.

    I can suggest making a feature request and based on its popularity we may implement a solution which will cover the desired end result:

    http://kendoui-feedback.telerik.com/forums/127393-kendo-ui-feedback/category/63716-data-source

    Regards,
    Stefan
    Progress Telerik
    Try our brand new, jQuery-free Angular components built from ground-up which deliver the business app essential building blocks - a grid component, data visualization (charts) and form elements.
  9. Sam
    Sam avatar
    34 posts
    Member since:
    Dec 2016

    Posted 08 Nov 2017 in reply to Stefan Link to this post

    Thanks Stefan, could you please let me know, what is the recommended approach for using kendo UI in a SPA with a asp.net restfull API?
  10. Stefan
    Admin
    Stefan avatar
    2880 posts

    Posted 10 Nov 2017 Link to this post

    Hello, Sam,

    In general, there are no specific requirements when using Kendo UI in SPA applications, and they all can be used based on the preferred technology which will be used in the SPA application.

    I can suggest checking our wrapper and native widget for some of the SPA oriented technologies:

    1) Kendo UI for AngularJS(directives of the jQuery widgets):

    https://docs.telerik.com/kendo-ui/AngularJS/introduction

    2) Kendo UI for Angular 2+ (native widgets):

    https://www.telerik.com/kendo-angular-ui/

    3) Kendo UI wrappers for React:

    https://docs.telerik.com/kendo-ui-wrappers-react/introduction

    All of the others Kendo UI widgets can be used as well.

    Please let me know if you need more details on one of the technologies.

    Also, please have in mind that we will appreciate if a separate ticket is submitted when the new question is not directly related to the first one, as this is helping us to determine which scenarios are most commonly used and based on that to improve the documentation in that direction.
     
    Regards,
    Stefan
    Progress Telerik
    Try our brand new, jQuery-free Angular components built from ground-up which deliver the business app essential building blocks - a grid component, data visualization (charts) and form elements.
Back to Top