Webforms ASP.NET Ajax JSON Not Valid

Webforms ASP.NET Ajax JSON Not Valid

rettore84rettore84 Posts: 7Questions: 1Answers: 0

Hello,

I'm trying to start with a simple Webforms ASP.NET 4.6.5 application using DataTables. I've downloaded the sample project and imported the sample database. Now I'm trying to send the data from the ASPX server-side to the client-side. The request is returning a JSON not valid. I'm a little unfamiliar with some of the concepts, I cannot understand what is wrong with the JSON generated sent and received. It seems like the same data sent is being received. I've attached the response received on the client side and well the JSON data being sent. On the console, it shows JSON is not valid(image attached)

The server-side code is here(I've pieced it together from the sample project and other examples from this forum) :

        [WebMethod]
        public static string Get_data()
        {
            var request = HttpContext.Current.Request;
            var settings = Properties.Settings.Default;

            using (var db = new Database(settings.DbType, settings.DbConnection))
            {
                var response = new Editor(db, "datatables_demo")
                .Model<StaffModel>()
                .Field(new Field("first_name")
                    .Validator(Validation.NotEmpty())
                )
                .Field(new Field("last_name"))
                 .Field(new Field("age")
                    .Validator(Validation.Numeric())
                    .SetFormatter(Format.IfEmpty(null))
                )
                .Field(new Field("extn")
                    .Validator(Validation.Numeric())
                )
                .Field(new Field("start_date")
                    .Validator(Validation.DateFormat(
                        Format.DATE_ISO_8601,
                        new ValidationOpts { Message = "Please enter a date in the format yyyy-mm-dd" }
                    ))
                    .GetFormatter(Format.DateSqlToFormat(Format.DATE_ISO_8601))
                    .SetFormatter(Format.DateFormatToSql(Format.DATE_ISO_8601))
                )
                .Field(new Field("salary")
                    .Validator(Validation.Numeric())
                    .SetFormatter(Format.IfEmpty(null))
                )
                .Process(request)
                .Data();

             //   HttpContext.Current.Response.ContentType = "text/json";
             //    HttpContext.Current.Response.Write(JsonConvert.SerializeObject(response));
             //    HttpContext.Current.Response.End();
             var serializer = new JavaScriptSerializer();
             string jsonResult = serializer.Serialize(response);
             return jsonResult;

            }

The client side is here:


<script type="text/javascript"> var editor; // use a global for the submit and return data rendering in the examples $(document).ready(function () { editor = new $.fn.dataTable.Editor({ "ajax": { type: 'POST', url: 'Ajax.aspx/Get_data', contentType: 'application/json; charset=utf-8', dataType: 'json', dataSrc: function (response) { var tr = JSON.parse(response.d); console.log(tr); return tr; } }, "table": "#example", "fields": [{ "label": 'First name:', "name": 'first_name' }, { "label": 'Last name:', "name": 'last_name' }, { "label": 'Age:', "name": 'age' }, { "label": 'Extension:', "name": 'extn' }, { "label": 'Start date:', "name": 'start_date', "type": 'datetime' }, { "label": 'Salary:', "name": 'salary' } ], }); new DataTable('#example', { "ajax": { type: 'POST', url: 'Ajax.aspx/Get_data', contentType: 'application/json; charset=utf-8', dataType: 'json', dataSrc: function (response) { var tr = JSON.parse(response.d); console.log(tr); return tr; } }, "columns": [ { "data": null, "render": (data) => data.first_name + ' ' + data.last_name }, { "data": 'age' }, { "data": 'extn' }, { "data": 'start_date' }, { "data": 'salary', render: DataTable.render.number(null, null, 0, '$') } ], "layout": { "topStart": { "buttons": [ { "extend": 'create', editor: editor }, { "extend": 'edit', editor: editor }, { "extend": 'remove', editor: editor } ] } }, select: true }); }); </script>

I appreciate the help. Let me know if further information is needed.



Answers

  • rettore84rettore84 Posts: 7Questions: 1Answers: 0

    https://justpaste.it/izhvo

    JSON datafrom Visual Studio inspector.

  • kthorngrenkthorngren Posts: 21,629Questions: 26Answers: 5,010
    edited February 1

    I have a feeling that tr is still a string. Change the console output to use typeof to see what tr is, like this:

                        dataSrc: function (response) {
                            var tr = JSON.parse(response.d);
                            console.log(typeof tr);
                            return tr;
                        }
    

    What is the result? My guess is its a string not an object.

    I'm not familiar with ASP.NET but my guess is this:

         var serializer = new JavaScriptSerializer();
         string jsonResult = serializer.Serialize(response);
         return jsonResult;
    

    is converting the Datatables response data to a JSON string then ASP.NET is again serializing the full response resulting in jsonResult being serialized twice.

    If this is the case then you will need to either just return the raw data from the Get_data() function so its serialized once or add an additional JSON.parse() to ajax.dataSrc to convert tr to an object. For example:

                        dataSrc: function (response) {
                            var tr = JSON.parse(response.d);
                            tr = JSON.parse( tr );
                            console.log(tr);
                            return tr;
                        }
    

    Kevin

  • rettore84rettore84 Posts: 7Questions: 1Answers: 0

    Thanks Kevin. The data is still not displayed with with the added JSON.parse(). In the variable inspection the response.data holds the information:

    The console returns:

    Also with the raw data only from the server side the result is the same:

  • kthorngrenkthorngren Posts: 21,629Questions: 26Answers: 5,010
    edited February 1

    It looks like you might not need to use JSON.parse() as it looks like the reposnse data has already been parsed to a Javascript object. Possibly just pointing to the response.d.data using ajax.dataSrc is all you need. For example:

    "ajax": {
        type: 'POST',
        url: 'Ajax.aspx/Get_data',
        contentType: 'application/json; charset=utf-8',
        dataType: 'json',
        dataSrc: 'response.d.data'
    },
    

    Kevin

  • kthorngrenkthorngren Posts: 21,629Questions: 26Answers: 5,010

    I ,made some edits to my previous response. See above.

    Kevin

  • rettore84rettore84 Posts: 7Questions: 1Answers: 0

    Thanks Kevin! That almost did the trick. I can now have the data displayed with this:

      "ajax": {
                        type: 'POST',
                        url: 'Ajax.aspx/Get_data',
                        contentType: 'application/json; charset=utf-8',
                        dataType: 'json',                    
                        dataSrc: function (response) {
                         var tr = response.data;
                         console.log(typeof tr);
                         return tr;
                        }
                    }
    

    But one last thing. The New, Edit and Delete functions do not function properly. When I click any of these buttons, the modal pop-up appears, but when I click on Create, Update or Delete(on each modal pop-up) nothing happens, the pop-up does not close and the data does not get updated. What could I be missing? Here is the client side Editor related code:

    <%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Ajax.aspx.cs" Inherits="DataTables_Editor.Ajax" %>
    
    <!DOCTYPE html>
    
    <html xmlns="http://www.w3.org/1999/xhtml">
    <head runat="server">
        <title></title>
        <link href="DataTables/datatables.min.css" rel="stylesheet" />
        <link href="https://cdn.datatables.net/buttons/3.2.1/css/buttons.dataTables.css" rel="stylesheet" />
        <link href="https://cdn.datatables.net/select/3.0.0/css/select.dataTables.css" rel="stylesheet" />
        <link href="https://cdn.datatables.net/datetime/1.5.5/css/dataTables.dateTime.min.css" rel="stylesheet" />
        <link href="css/editor.dataTables.css" rel="stylesheet" />
    
        <script src="Scripts/jquery-3.4.1.min.js" type="text/javascript"></script>
        <script src="DataTables/datatables.min.js"></script>
        <script src="https://cdn.datatables.net/buttons/3.2.1/js/dataTables.buttons.js"></script>
        <script src="https://cdn.datatables.net/buttons/3.2.1/js/buttons.dataTables.js"></script>
        <script src="https://cdn.datatables.net/select/3.0.0/js/dataTables.select.js"></script>
        <script src="https://cdn.datatables.net/select/3.0.0/js/select.dataTables.js"></script>
        <script src=" https://cdn.datatables.net/datetime/1.5.5/js/dataTables.dateTime.min.js"></script>
        <script src="js/dataTables.editor.js"></script>
        <script src="js/editor.dataTables.js"></script>
    
        <script type="text/javascript">
            var editor; // use a global for the submit and return data rendering in the examples
            
            $(document).ready(function () {
                editor = new $.fn.dataTable.Editor({
                    "ajax": {
                        type: 'POST',
                        url: 'Ajax.aspx/Get_data',
                        contentType: 'application/json; charset=utf-8',
                        dataType: 'json',
                        
                        dataSrc: function (response) {
                            var tr = response.data;
                            console.log(typeof tr);
                            return tr;
                        }
                    },
                    "table": "#example",
                    "fields": [{
                        "label": 'First name:',
                        "name": 'first_name'
                    },
                    {
                        "label": 'Last name:',
                        "name": 'last_name'
                    },
                    {
                        "label": 'Age:',
                        "name": 'age'
                    },
                    {
                        "label": 'Extension:',
                        "name": 'extn'
                    },
                    {
                        "label": 'Start date:',
                        "name": 'start_date',
                        "type": 'datetime'
                    },
                    {
                        "label": 'Salary:',
                        "name": 'salary'
                    }
                    ],
                });
    
    
                new DataTable('#example', {
                    "ajax": {
                        type: 'POST',
                        url: 'Ajax.aspx/Get_data',
                        contentType: 'application/json; charset=utf-8',
                        dataType: 'json',
                        dataSrc: function (response) {
                            var tr = response.data;
                            console.log(typeof tr);
                            return tr;
                        }
                    },
                    "columns": [
                        {
                            "data": null,
                            "render": (data) => data.first_name + ' ' + data.last_name
                        },
                        { "data": 'age' },
                        { "data": 'extn' },
                        { "data": 'start_date' },
                        { "data": 'salary', render: DataTable.render.number(null, null, 0, '$') }
                    ],
                    "layout": {
                        "topStart": {
                            "buttons": [
                                { "extend": 'create', editor: editor },
                                { "extend": 'edit', editor: editor },
                                { "extend": 'remove', editor: editor }
                            ]
                        }
                    },
                    "select": true,
                    "processing": true,
                });
    
            });
        </script>
    </head>
    
  • kthorngrenkthorngren Posts: 21,629Questions: 26Answers: 5,010

    The Editor's ajax option does not have a dataSrc option. It expects the data to be returned in the format discussed in the Client / server docs. I believe the only option to do something similar is to use the ajax option as a function. See the last example in the docs. Probably you will need something like this:

        ajax: function (method, url, data, success, error) {
            $.ajax({
                type: method,
                url: url,
                data: data,
                dataType: 'json',
                success: function (json) {
                    success(json.data);
                },
                error: function (xhr, error, thrown) {
                    error(xhr, error, thrown);
                }
            });
        }
    

    Call the success callback like this success(json.data);.

    Kevin

  • rettore84rettore84 Posts: 7Questions: 1Answers: 0

    Thanks again. I can get the data displayed with the following(again piecing from other posts from this forum):

     $(document).ready(function () {
                editor = new $.fn.dataTable.Editor({
                    "ajax": {
                        url: 'Ajax.aspx/Get_data',
                        data: function (d) {
                            return JSON.stringify(d);
                        },
                        type: "POST",
                        contentType: "application/json"
                    },
                    "idSrc": "id",
                    "table": "#example",
                    "fields": [{ ...
    
    
     new DataTable('#example', {
                    "ajax": {
                        url: 'Ajax.aspx/Get_data',
                        data: function (d) {
                            return JSON.stringify(d);
                        },
                        type: "POST",
                        contentType: "application/json"
                    },
                    "columns": [
                        {.....
    

    When I click the create button the modal pop-up appears but after inserting the information and clicking creating nothing happens. When clicking on Edit or Delete, I get the following error( the idSrc has been added to the ajax parameters):

    I apologize, I acknowledge I might be missing basic code here, I just can't seem to find the right information. I apreciate all the help.

  • kthorngrenkthorngren Posts: 21,629Questions: 26Answers: 5,010

    Have you read the technote at the link in the error?
    https://datatables.net/manual/tech-notes/14

    You have "idSrc": "id",. Does your row data have an id object?

    Looking back at your sample JSON output you don't have an id but do have the default DT_RowId. Note this comment in the technote:

    If your unique identifier information is not under the name DT_RowId, but is under some other data property name, use the idSrc option to tell Editor where to find it.

    If you are using DT_RowId for your unique identifier then you don't need to define idSrc as DT_RowId is the default value.

    Kevin

  • kthorngrenkthorngren Posts: 21,629Questions: 26Answers: 5,010

    Use the browser's network inspector tool to monitor the XHR requests and responses. This will allow you to validate that the responses meet the Editor client/server data requirements. If the response is in the response.d object then you will need to use the Editor's ajax as a function to extract the required data structure.

    Kevin

  • rettore84rettore84 Posts: 7Questions: 1Answers: 0

    Thanks. Removing the idSRC fixed the issue. However, the New, Edit, and Delete still don't update the DB.

    Here is the Network inspector when I click Update:

    On the server side the Params field from Http.Request is empty:

    When I test the sample project the Param field is populated:

    Here the Network Inspector:

    Any idea where I could start troubleshooting this?

  • allanallan Posts: 63,966Questions: 1Answers: 10,547 Site admin

    Try removing:

                       data: function (d) {
                           return JSON.stringify(d);
                       },
    

    If you are using the Editor server-side libraries, they will parse the POSTed data, so no need to send it as a JSON string in the request body. Regular HTTP parameters will do fine.

    Allan

  • rettore84rettore84 Posts: 7Questions: 1Answers: 0

    Unfortunately that did not work. But thank you for the help!

  • allanallan Posts: 63,966Questions: 1Answers: 10,547 Site admin

    Are you able to PM me a link to the page in question?

    If you look at the "Payload" section of the Ajax request when you make a create or edit action, does it now show all of the parameters being submitted?

    Allan

  • lucas84lucas84 Posts: 4Questions: 0Answers: 0
    edited February 6

    Sorry for the delay. I'm running a local project,, still in development with Visual Studio, so I'm not sure how I could expose for external access. As for the Payload here is what I get when I edit a row:

    I have this:

    data: function (d) {
        return JSON.stringify(d);
    },
    

    If I remove it as you suggested I get an error 500.

  • allanallan Posts: 63,966Questions: 1Answers: 10,547 Site admin

    Could you also try removing contentType: 'application/json; charset=utf-8', please? I think that is telling .NET to expect JSON in the request body. We just want HTTP parameters like in the demo package.

    Allan

  • lucas84lucas84 Posts: 4Questions: 0Answers: 0

    I removed it then I get this error:

  • kthorngrenkthorngren Posts: 21,629Questions: 26Answers: 5,010

    Did you follow the troubleshooting steps at the link in the error?
    https://datatables.net/manual/tech-notes/1

    Let us know what you find.

    Kevin

  • lucas84lucas84 Posts: 4Questions: 0Answers: 0

    Hi Kevin, I did. The result of the debugging are the screenshots of my reply on Feb-2nd, where is the Params field from Http.Request is empty, and my reply on Feb-05 with a screenshot of the Network monitor of the Payload. Thanks for all the help.

  • kthorngrenkthorngren Posts: 21,629Questions: 26Answers: 5,010

    The Payload tab shows the data sent to the server. Look at the Preview or Response tabs to see the response.

    Its better to post the current screenshots than to refer to old screenshots that weren't generated from the current error. Its better for us to troubleshoot rather than assume something and troubleshoot the wrong thing.

    Kevin

  • lucas84lucas84 Posts: 4Questions: 0Answers: 0

    Hi Kevin, I ende up up adopting a different approach, utilizing the controller method. Thanks for all the help.

Sign In or Register to comment.