JQGrid - 无法调用 ASP.NET WebMethod,但可以使用 Ajax

发布于 2024-10-19 23:10:00 字数 4406 浏览 5 评论 0原文

我是 jqGrid 的新手,我发现很难遵循文档 jqGrid 文档

我不知道如何在设置 JQGrid 时调用 WebMethod。我已成功进行 Ajax 调用来获取数据,然后使用本地数据设置 JQGrid。我认为这是设置过程中的一个额外步骤,我应该能够使用 url 属性提供 webmethod 的路径。

editurl 属性也是同样的方法。我实际上从未收到服务器的帖子。

原始代码

尝试 JQGrid 设置


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); 

        }

当前代码

我现在可以正常工作了,但我还有最后一个问题。为什么我必须设置“repeatims: false”才能显示内容?

使其正常工作的一些注意事项包括设置 ajax 请求的不同方法。

(Ajax:类型)是(jqgrid:mtype) (Ajax: contentType) 是 (jqgrid : ajaxGridOptions: { contentType: })

最后从文档中了解如何设置 JSONReader。

希望这对其他人有帮助,并感谢奥列格的所有帮助。

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 方法


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

列表中的一个 JSON 对象


{"__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}

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}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

风吹短裙飘 2024-10-26 23:10:01

为了让 jqGrid 与 WebMethod 一起工作,我也付出了很多努力。下面给出的是最终的效果。

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>

代码隐藏

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;
        }


    }
}

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;
        }


    }
}
心的憧憬 2024-10-26 23:10:00

首先,我希望答案中的代码示例可以对您有帮助(另请参阅这个答案< /a>)。主要思想是,

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" };

如果服务器未设置 rowspagetotalrecords 参数,只返回数据列表,就像您的情况一样,您可以使用以下 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; }
}

(请参阅 此处此处)。如果您不想实现服务器端数据分页、排序和过滤,我建议您使用 loadonce:true

而且你的代码有一些问题。第一个是您在 Web 方法中手动调用 JavaScriptSerializer.Serialize。如果您使用 dataType: "json",JSON 响应将通过 $.ajax 转换为对象。你的情况也是如此。因此,success 处理程序的 msg 参数具有 d 属性。但 msg.d 不是对象,而是又一个 JSON 字符串,您可以使用 eval(msg.d) 将其转换为对象。原因是你的方法的结果将再次转换为 JSON。

要解决此问题,您应该将 Web 方法 GetUsersJSON 更改为以下内容:

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

然后您可以将前面示例中的 data: eval(msg.d) 更改为 data :msg.d

通常,我们会为 Web 方法使用附加的 [ScriptMethod (ResponseFormat = ResponseFormat.Json)][ScriptMethod (UseHttpGet = true, ResponseFormat = ResponseFormat.Json)] 属性,但是在很多情况下(似乎也在你的情况下)它是不需要的。

使用ajaxGridOptionsserializeGridDatajsonReader后,jqGrid就可以读取页面数据,但数据必须是JSON格式,而不是JSON格式。两次编码的 JSON 格式。

更新:您要求我评论为什么您需要在 jsonReader 中使用 repeatitems:false 设置才能读取您的数据。对于理解 jsonReader 的工作原理来说,这是一个很重要的问题,但答案会占据一点位置。

一般来说,jqGrid 的 JSON 数据格式化有两种主要方式。它应该是网格行的数据数组。数组的每个项目代表网格中的行,并且该行应该是以下两种主要形式之一:

1)作为具有命名属性的对象,例如

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

或 2)字符串数组

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

,例如

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

jqGrid 映射“true”和“1”在 edittype:'checkbox' 设置的情况下,值为布尔值“true”。您如何理解如果网格有许多复选框列,则使用“1”/“0”格式可以减少传输数据的大小。

repeatitems:false 选项意味着 jqGrid 应该扫描 JSON 数据以获取数据的第一个(对象样式)表示形式。 repeatitems:true 表示第二个(数组样式)表示形式。

顺便说一句,如果您使用对象样式 (repeatitems:false),jsonReadercell 设置将不使用 并且您可以删除您使用的 cell:'' 设置。

如果网格中有一列具有唯一值,则数字形式的 jsonReaderid 选项非常实用。选项 id:'0' 表示“用户名”列的值将用作行 id。如果您使用 IE 或 Chrome 的开发者工具的 Firebug 检查网格,您将看到相应的 元素具有属性 id="TestUser" (在您的数据)。由于在一个 HTML 页面上不允许出现重复的 id,因此您可以理解,使用正确的唯一 id 定义网格非常重要。如果 jqGrid 在数据中找不到 id 列,它将使用 ids“1”、“2”... 因此,如果您看到网格具有值,您应该在 id 中搜索错误jsonReader 的属性。

接下来重要的是两种数据表示方式的优缺点:对象样式 (repeatitems:false) 和数组样式 (repeatitems:true)

对象样式有在两种主要情况下,

  1. 您希望只在服务器上发布现有对象,并尽可能减少工作量(快速而肮脏的解决方案),
  2. 您可以从无法更改接口的服务器获取数据。

在所有其他情况下,数组样式 (repeatitems:true) 与对象样式相比具有优势。主要从那里

  1. 以对象样式表示将频繁地根据需要发送更多数据。在您的示例中,例如将发送“Comment”属性,jqGrid 不会使用该属性。
  2. 数组样式的数据更加紧凑,因为您不会在每一行中传输属性名称(常量)。

因此,如果您想减少传输数据的大小并且可以在服务器端进行更改,我建议您使用数组样式(repeatitems:true)来表示数据。在这种情况下,可以很好地使用 jsonReadercell:'' 属性。

我建议您查看 jqGrid 文档的部分 jsonReaderxmlReaderlocalReader

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文