【问题标题】:JQGrid - Cannot call ASP.NET WebMethod but can with AjaxJQGrid - 无法调用 ASP.NET WebMethod 但可以使用 Ajax
【发布时间】:2011-07-06 19:30:37
【问题描述】:

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

在设置 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]
        public static string GetUsersJSON()
        {
            var users = new List();
            using(UserAdministrationSandboxDataContext uasd = new UserAdministrationSandboxDataContext())
            {
                users = uasd.GetUserList();                
            }
            JavaScriptSerializer serializer = new JavaScriptSerializer();
            return serializer.Serialize(users); 

        }

当前代码

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

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

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

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

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

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

网络方法


        [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":"TestUser@test.com","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}

【问题讨论】:

    标签: jquery asp.net json jqgrid webmethod


    【解决方案1】:

    为了让 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;
            }
    
    
        }
    }
    

    【讨论】:

      【解决方案2】:

      首先,我希望the answer 中的代码示例对您有所帮助(另请参阅this answer)。主要思想是,您应该使用以下附加的 jqGrid 参数

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

      (参见herehere)。如果您不想实现服务器端数据分页、排序和过滤,我建议您使用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格式。

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

      一般来说,有两种主要样式可以为 jqGrid 格式化 JSON 数据。它应该是网格行的数据数组。数组的每一项都代表网格中的行,行应该是两个主要形式之一

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

      {"Username":"TestUser","Email":"TestUser@test.com","Comment":"..","IsApproved":true}
      

      或 2) 字符串数组,如

      ["TestUser","TestUser@test.com","true"]
      

      ["TestUser","TestUser@test.com","1"]
      

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

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

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

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

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

      对象样式在两种主要情况下具有优势

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

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

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

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

      我建议您通过the part of jqGrid documentation 了解jsonReaderxmlReaderlocalReader

      【讨论】:

      • 感谢 Oleg 的帮助,我可以从您对 WebMethod 和 JSONReader 设置的回答中看到一些错误,但即使让 jqgrid 在没有明确使用 $ 的情况下进行 ajax 调用,我仍然遇到问题.ajax。我现在正在尝试触发这部分。
      • @Scruffy The Janitor:您应该使用您使用的新代码以及来自服务器响应的 JSON 附加您的问题。 FiddlerFirebug 可以在这里为您提供帮助。
      • @Scruffy:我如何在我的问题中写下您必须从 Web 方法中删除手动序列化 (JavaScriptSerializer ),因为您现在没有 JSON 序列化数据,而是两次序列化数据。您当前的伪代码是 MakeJson({d:MakeJson(users)}) 而不是 MakeJson({d:users})
      • @Oleg:感谢您到目前为止的帮助,您在回答中的示例让我走得更远,现在正在努力读取和显示 JSON 内容。顺便说一句,我用当前代码更新了问题。
      • @Scruffy:在web方法GetUsersJSON中输入List是什么?不应该是List&lt;User&gt;吗? uasd.GetUserList() 返回的列表中的项目属于哪种类型?您是否在 Fiddler 或 Firebug 中验证了哪些数据将被发送回 jqGrid。如果您将数据也作为问题的一部分发布,那就太好了。您可以缩短数据并修改一些机密数据。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2023-03-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多