JQGrid - Cannot call ASP.NET WebMethod but can with Ajax
Asked Answered
K

2

5

I am new to jqGrid and I have found it difficult to follow the documentation jqGrid Documentation

I cannot figure out how to call a WebMethod when setting up the JQGrid. I have been successful in making an Ajax call to get the data and then setting up the JQGrid with local data. I think its an extra step in the setup process and that I should be able to provide the path to the webmethod using the url property.

The editurl property is the same way. I am never actually receiving the post to the server.

Original Code

Attempted JQGrid Setup


function GetData()
{
    $('#list').jqGrid({
        type: "POST",
        url: "Default.aspx/GetUsersJSON",
        datatype: "json",
        height: 250,
        colName: ['Username', 'Email'],
        colModel: [
                ...
    }).jqGrid(
                'navGrid',
                '#pager',
                {
                    edit: true,
                    add: true,
                    del: true
                });
}

WebMethod



        [WebMethod]
        public static string GetUsersJSON()
        {
            var users = new List();
            using(UserAdministrationSandboxDataContext uasd = new UserAdministrationSandboxDataContext())
            {
                users = uasd.GetUserList();                
            }
            JavaScriptSerializer serializer = new JavaScriptSerializer();
            return serializer.Serialize(users); 

        }

Current Code

I got it working correctly now, but I still have one final question. Why did I have to set the 'repeatitems: false' in order to display the content?

Some of the caveats to get this to work include the different ways to setup the ajax request.

(Ajax: type) is (jqgrid : mtype) (Ajax: contentType) is (jqgrid : ajaxGridOptions: { contentType: })

And finally understanding the documentation from the documentation on how to setup the JSONReader.

Hope this helps others and thanks Oleg for all your help.

JS



function GetUserDataFromServer()
{
    $('#list').jqGrid({
        url: "Default.aspx/GetUsersJSON",
        mtype: 'POST',        
        ajaxGridOptions: { contentType: "application/json" },
        datatype: "json",
        serializeGridData: function (postData)
        {
            return JSON.stringify(postData);
        },
        jsonReader: {
            root: function (obj) { return obj.d; },
            page: function (obj) { return 1; },
            total: function (obj) { return 1; },
            records: function (obj) { return obj.d.length; },
            id:'0',
            cell:'',
            repeatitems: false            
        },
        datatype: "json",
        height: 250,
        colName: ['Username', 'Email'],
        colModel: [
                {
                    name: 'Username',
                    index: 'Username',
                    width: 100,
                    editable: true
                },
                {
                    name: 'Email',
                    index: 'Email',
                    width: 220,
                    editable: true
                },
                {
                    name: 'IsLockedOut',
                    index: 'IsLockedOut',
                    width: 100,
                    editable: true,
                    edittype: 'checkbox'
                }
        ],
        caption: "Users"
    })
}

Web Method


        [WebMethod]
        [ScriptMethod(ResponseFormat = ResponseFormat.Json)]
        public static List GetUsersJSON()
        {
            using (UserAdministrationSandboxDataContext uasd = new UserAdministrationSandboxDataContext())
            {
                return uasd.GetUserList();
            }
        }

One JSON Object from the List


{"__type":"UserAdministrationSandbox.UserData","PKID":"00000000-0000-0000-0000-000000000001","Username":"TestUser","ApplicationName":"Test","Email":"[email protected]","Comment":"TestUser","Password":"D41D8CD98F00B204E9800998ECF8427E","PasswordQuestion":"Is this a blank Password?","PasswordAnswer":null,"IsApproved":true,"LastActivityDate":"\/Date(1298869200000)\/","LastLoginDate":"\/Date(1298869200000)\/","LastPasswordChangedDate":"\/Date(1298869200000)\/","CreationDate":"\/Date(1298869200000)\/","IsOnLine":false,"IsLockedOut":false,"LastLockedOutDate":"\/Date(1298869200000)\/","FailedPasswordAttemptCount":0,"FailedPasswordAttemptWindowStart":null,"FailedPasswordAnswerAttemptCount":null,"FailedPasswordAnswerAttemptWindowStart":null}
Kearns answered 1/3, 2011 at 20:37 Comment(0)
L
12

First of all I hope the code examples from the answer could help you (see also this answer). The main idea, that you should use following additional jqGrid parameters

ajaxGridOptions: { contentType: 'application/json; charset=utf-8' },
serializeGridData: function (postData) {
    return JSON.stringify(postData);
},
jsonReader: { root: "d.rows", page: "d.page", total: "d.total",
              records: "d.records" };

If the server not set rows, page, total and records parameter in the response and just return the list of data like in your case you can use the following jsonReader

jsonReader: {
    root: function (obj) { return obj.d; },
    page: function (obj) { return 1; },
    total: function (obj) { return 1; },
    records: function (obj) { return obj.d.length; }
}

(see here and here). In the case if you don't want implement server side data paging, sorting and filtering I recommend you to use loadonce:true.

Moreover your code have some problems. The first one is that you call JavaScriptSerializer.Serialize manually in your web method. If you use dataType: "json" the JSON response will be converted to object by $.ajax. It is so in your case also. Because of that the msg parameter of the success handler has d property. But msg.d is not the object, but one more JSON string which you convert to object with eval(msg.d). The reason is that the results of your method will be converted to JSON one more time.

To fix the problem you should change the web method GetUsersJSON to the following:

[WebMethod]
[ScriptMethod (ResponseFormat = ResponseFormat.Json)]
public static List<User> GetUsersJSON()
{
    using(UserAdministrationSandboxDataContext uasd =
                                    new UserAdministrationSandboxDataContext())
    {
        return uasd.GetUserList();                
    }
}

then you can place data: eval(msg.d) in your previous example to data: msg.d.

Typically one use additional [ScriptMethod (ResponseFormat = ResponseFormat.Json)] or [ScriptMethod (UseHttpGet = true, ResponseFormat = ResponseFormat.Json)] attribute for the web method, but in many cases (it seems also in your case) it is not needed.

After the usage of ajaxGridOptions, serializeGridData and jsonReader jqGrid will able to read the page of data, but the data should be in JSON format and not twice encoded JSON format.

UPDATED: You ask me to comment why you need to use repeatitems:false setting in the jsonReader to be able to read your data. It is important question for understanding how jsonReader work, but the answer will take a little place.

In general there are two main styles how the JSON data can be formatted for jqGrid. It should be array of data for grid rows. Every item of the array represent the row in grid and the row should be in one from the two main form

1) as an object with named properties like

{"Username":"TestUser","Email":"[email protected]","Comment":"..","IsApproved":true}

or 2) an array of strings like

["TestUser","[email protected]","true"]

or

["TestUser","[email protected]","1"]

jqGrid map both "true" and "1" values to the boolean value "true" in case of edittype:'checkbox' setting. How you can understand if the grid has many checkbox-columns the usage of "1"/"0" format can reduce the size of transfered data.

The repeatitems:false option means that jqGrid should scan JSON data for the first (object style) representation of data. The repeatitems:true means the second (array style) representation.

By the way if you use the object style (repeatitems:false) the cell setting of the jsonReader will be not used and you can remove cell:'' setting which you use.

The id option of the jsonReader in numeric form is practical if you have one column in the grid with unique values. The option id:'0' means that the value of the column "Username" will be used as the row id. If you examine the grid with Firebug of Developer tools of IE or Chrome you will see that the corresponding <tr> element has attribute id="TestUser" (used in your data). Because duplicate in ids are not allowed on one HTML page, you can understand that it is very important to define grid with correct unique ids. If jqGrid not find id column in the data it will use ids "1", "2", ... So if you see that your grid has the values you should search for the error in the id property of the jsonReader.

The next important thing is the advantages and disadvantages of two ways of the data representation: object style (repeatitems:false) and array style (repeatitems:true)

The object style has advantage in two main cases

  1. you want just post existing objects with as less work on the server as possible (quick and dirty solution)
  2. you get data from the server which interface you can not change.

In all other situations the array style (repeatitems:true) has advantages compared with the object style. The main from there

  1. In the object style representation will be send frequently more data as needed. In your example the "Comment" property for example will be send which will not be used by jqGrid.
  2. The data from array style are much more compacter because you will not transfer the name of properties (which are constants) in every row.

So if you want to reduce the size of transfered data and you can make changes on the server side I would recommend you to use array style (repeatitems:true) of representation of data. In the case the cell:'' property of the jsonReader can be good used.

I recommend you to look though the part of jqGrid documentation about jsonReader, xmlReader and localReader.

Laundress answered 1/3, 2011 at 21:23 Comment(11)
Thanks for the help Oleg, I can see some of the mistakes from your answer with the WebMethod and the JSONReader setup but I am still having issues even getting the jqgrid to make the ajax call without explicitly using $.ajax. I am trying to firebug this part now.Kearns
@Scruffy The Janitor: You should append your question with the new code which you use and also the JSON from the server response. The Fiddler or Firebug can help you here.Laundress
@Scruffy: How I write in my question you have to remove manual serialization (JavaScriptSerializer ) from the web method because you has now not JSON serialized data, but twice serialized data. you current psoudo code is MakeJson({d:MakeJson(users)}) instead of MakeJson({d:users})Laundress
@Oleg: Thank you for your help so far, your examples in your answer have got me farther, now working on getting the JSON content read and displaying. BTW, I updated the question with the current code.Kearns
@Scruffy: What is List type in the web method GetUsersJSON? Should it be not List<User>? Which type has the item from the list returned by uasd.GetUserList()? Do you verified in the Fiddler or Firebug which data will be send back to jqGrid. It would be nice if you posted the data also as the part of your question. You can make the data shorter and modify some confidential data.Laundress
@Oleg:Actually I got it working, if you still want the data its all made up data since I am still prototyping this out. The only issue that I still have is why I had to include repeatitems: false to get the content to display. The Question was modified with all the up to date information.Kearns
@Scruffy: To answer on your question I need have one line of the JSON data which you post. You don't include definition of the items of the uasd.GetUserList() class so I don't know whether you have the List<List<string>> or List<User> where the User class has string property Username, Email and boolean property IsLockedOut. The usage of repeatitems: false or repeatitems: true depend on the format of data.Laundress
@Scruffy:: Are JSON data placed in the [] - array? Do you return one element of the list?Laundress
@Oleg: it is in the [] - array. I just copied one element from the arrayKearns
@Scruffy: I append my answer with more information. One more remark the setting loadonce:true can be helpful for you current grid. It allows you to use local paring, sorting and filtering (searching) of data.Laundress
@Oleg: thanks again for all your help. Your comments have been extremely helpfulKearns
W
0

I also struggled a lot to get jqGrid working with WebMethod. Given below is what worked at the end.

ASPX

<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="GridTest.aspx.cs" Inherits="SMFLWeb.GridTest" %>
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
    <title></title>
    <!--  jQuery-UI theme Redmond is used. The UI iles should be copied to the following location -->
    <link rel="stylesheet" type="text/css" media="screen" href="css/Redmond/jquery-ui.css" />

    <!--  This is a CSS file from jqGrid download -->
    <link rel="stylesheet" type="text/css" media="screen" href="css/ui.jqgrid.css" />

    <!--  jQuery file -->
    <script src="Scripts/jquery-1.11.3.min.js"></script>

    <!--  Following two jqGrid Script Files.  -->
    <script src="js/i18n/grid.locale-en.js" type="text/javascript"></script>
    <script src="js/jquery.jqGrid.js" type="text/javascript"></script>

    <script>

        $(document).ready(function () {

            $("#grid").jqGrid({
                url: "GridTest.aspx/GetMyGames",
                mtype: 'POST',
                postData:
                {
                    useMyFilter: "1"
                },
                datatype: "json",
                ajaxGridOptions: { contentType: 'application/json; charset=utf-8' },
                serializeGridData: function (postData) {
                    return JSON.stringify(postData);
                },
                jsonReader: {
                    repeatitems: false,
                    root: function (obj) { return obj.d; }
                },
                colNames: ['GameID', 'GameName'],
                colModel: [
                    { name: 'GameID', index: 'GameID', width: 250},
                    { name: 'GameName', index: 'GameName', width: 250}
                ],
                rowNum: 2,
                /*rowList: [10, 20, 30],*/
                pager: '#pager2',
                sortname: 'id',
                viewrecords: true,
                sortorder: "desc",
                caption: "JSON Example",
                gridview: true,
                height: "auto",
                loadonce: true,
                recordtext: "Records {0} - {1} of {2}",
                emptyrecords: "No records to view",
                loadtext: "Loading...",
                pgtext: "Page {0} of {1}"
            });


        });


    </script>
</head>
<body>
    <form id="form1" runat="server">
        <div>
            <table id="grid"></table>
            <div id="pager2"></div>

        </div>
    </form>
</body>
</html>

Code Behind

namespace SMFLWeb
{
    public partial class GridTest : System.Web.UI.Page
    {
        protected void Page_Load(object sender, EventArgs e)
        {

        }
        [System.Web.Services.WebMethod(BufferResponse = false)]
        public static List<Game> GetMyGames(string useMyFilter)
        {
            List<Game> games = new List<Game>();
            Game g1 = new Game();
            g1.GameID = 1;
            g1.GameName = "A";

            Game g2 = new Game();
            g2.GameID = 2;
            g2.GameName = "B";

            Game g3 = new Game();
            g3.GameID = 3;
            g3.GameName = "C";

            Game g4 = new Game();
            g4.GameID = 4;
            g4.GameName = "D";

            Game g5 = new Game();
            g5.GameID = 5;
            g5.GameName = "E";

            games.Add(g1);
            games.Add(g2);
            games.Add(g3);
            games.Add(g4);
            games.Add(g5);

            return games;
        }


    }
}
Wow answered 19/7, 2015 at 0:55 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.