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

我是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); } 

现行守则

我现在正常工作,但我还有一个最后的问题。 为什么我必须设置’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} 

首先,我希望答案中的代码示例可以帮助您(另请参阅此答案 )。 主要思想是,您应该使用以下附加的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; } } 

(见这里和这里 )。 如果您不希望实现服务器端数据分页,排序和过滤,我建议您使用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 GetUsersJSON() { using(UserAdministrationSandboxDataContext uasd = new UserAdministrationSandboxDataContext()) { return uasd.GetUserList(); } } 

然后你可以将data: eval(msg.d)前一个例子中的data: eval(msg.d)放到data: msg.d

通常,对Web方法使用额外的[ScriptMethod (ResponseFormat = ResponseFormat.Json)][ScriptMethod (UseHttpGet = true, ResponseFormat = ResponseFormat.Json)]属性,但在许多情况下(在您的情况下似乎也是如此)它不是需要。

在使用ajaxGridOptionsserializeGridDatajsonReader jqGrid将能够读取数据页面,但数据应该是JSON格式而不是两次编码的JSON格式。

更新 :你让我评论为什么你需要使用repeatitems:false jsonReader repeatitems:false设置能够读取你的数据。 理解jsonReader如何工作是一个重要的问题,但答案将占据一席之地。

通常,有两种主要样式可以如何为jqGrid格式化JSON数据。 它应该是网格行的数据数组。 数组中的每个项目都代表网格中的行,而行应该是两个主要forms中的一行

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

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

或2)像一串字符串

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

要么

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

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

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

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

如果网格中的一列具有唯一值,则数字forms的jsonReaderid选项是实用的。 选项id:'0'表示“Username”列的值将用作行id。 如果使用IE或Chrome的Firebug of Developer工具检查网格,您将看到相应的

元素具有属性id="TestUser" (在您的数据中使用)。 由于在一个HTML页面上不允许使用重复ID,因此您可以理解使用正确的唯一ID定义网格非常重要。 如果jqGrid在数据中找不到id列,它将使用id“1”,“2”,……所以如果你看到你的网格有值,你应该在jsonReaderid属性中搜索错误。

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

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

  1. 你想要在服务器上尽可能少地发布现有对象(快速和肮脏的解决方案)
  2. 您从服务器获取数据哪个界面无法更改。

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

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

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

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

我也努力让jqGrid与WebMethod合作。 以下是最终的结果。

ASPX

 <%@ Page Language="C#" AutoEventWireup="true" CodeBehind="GridTest.aspx.cs" Inherits="SMFLWeb.GridTest" %>                 

代码背后

 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 GetMyGames(string useMyFilter) { List games = new List(); 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; } } }