我有一个jqGrid我正在使用asp.Net Web Forms,它从数据库中正确显示所需的信息,但是它也显示了搜索选项,但如果我尝试搜索,请说出等于的名字Lijo,它只是没有显示那条记录。记录存在。我知道我遗漏了一些搜索所需要的东西,这里是代码
<script type="text/javascript">
$(function() {
$("#UsersGrid").jqGrid({
url: 'ModCust.ashx',
datatype: 'json',
height: 250,
width: 800,
colNames: ['Application No', 'First Name', 'Middle Name', 'Last Name'],
colModel: [
{ name: 'cApplicationNo', index: 'cApplicationNo', width: 100, sortable: true},
{ name: 'cFirstName', width: 100, sortable: true},
{ name: 'cMiddleName', width: 100, sortable: true },
{ name: 'cLastName', width: 100, sortable: true },
],
cmTemplate: { title: false},
rowNum: 10,
rowList: [10, 20, 30],
pager: '#UsersGridPager',
sortname: 'cApplicationNo',
viewrecords: true,
sortorder: 'asc',
caption: 'Customer Details'
});
$("#UsersGrid").jqGrid('navGrid', '#UsersGridPager', { edit: false, add: false, del: false });
});
</script>
这是我的ModCust.ashx处理程序
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Data;
using System.Data.SqlClient;
using System.Web;
using System.Web.Script.Serialization;
namespace CwizBankApp
{
public struct JQGridResults
{
public int page;
public int total;
public int records;
public JQGridRow[] rows;
}
public struct JQGridRow
{
public string id;
public string[] cell;
}
[Serializable]
public class User
{
public string ApplicationNo { get; set; }
public string FirstName { get; set; }
public string MiddleName { get; set; }
public string LastName { get; set; }
}
/// <summary>
/// Summary description for $codebehindclassname$
/// </summary>
public class ModCust : IHttpHandler
{
public void ProcessRequest(HttpContext context)
{
HttpRequest request = context.Request;
HttpResponse response = context.Response;
string _search = request["_search"];
string numberOfRows = request["rows"];
string pageIndex = request["page"];
string sortColumnName = request["sidx"];
string sortOrderBy = request["sord"];
int totalRecords;
//Collection<User> users = GetDummyUsers(numberOfRows, pageIndex, sortColumnName, sortOrderBy, out totalRecords);
Collection<User> users = GetUsers(numberOfRows, pageIndex, sortColumnName, sortOrderBy, out totalRecords);
string output = BuildJQGridResults(users, Convert.ToInt32(numberOfRows), Convert.ToInt32(pageIndex), Convert.ToInt32(totalRecords));
response.Write(output);
}
private string BuildJQGridResults(Collection<User> users, int numberOfRows, int pageIndex, int totalRecords)
{
JQGridResults result = new JQGridResults();
List<JQGridRow> rows = new List<JQGridRow>();
foreach (User user in users)
{
JQGridRow row = new JQGridRow();
row.id = user.ApplicationNo;
row.cell = new string[4];
row.cell[0] = user.ApplicationNo;
row.cell[1] = user.FirstName;
row.cell[2] = user.MiddleName;
row.cell[3] = user.LastName;
rows.Add(row);
}
result.rows = rows.ToArray();
result.page = pageIndex;
result.total = (totalRecords + numberOfRows - 1) / numberOfRows;
result.records = totalRecords;
return new JavaScriptSerializer().Serialize(result);
}
private Collection<User> GetDummyUsers(string numberOfRows, string pageIndex, string sortColumnName, string sortOrderBy, out int totalRecords)
{
var data = new Collection<User> {
new User(){ FirstName = "Bill", LastName = "Gates", ApplicationNo= "1", MiddleName = "Bill Gates"}
};
totalRecords = data.Count;
return data;
}
private Collection<User> GetUsers(string numberOfRows, string pageIndex, string sortColumnName, string sortOrderBy, out int totalRecords)
{
Collection<User> users = new Collection<User>();
string connectionString = "Server=Server;Database=CwizData;Trusted_Connection=True";
using (SqlConnection connection = new SqlConnection(connectionString))
{
using (SqlCommand command = new SqlCommand())
{
command.Connection = connection;
command.CommandText = "select cApplicationNo,cFirstName,cMiddleName,cLastName from Data_Customer_Log";
command.CommandType = CommandType.Text; // StoredProcedure;
SqlParameter paramPageIndex = new SqlParameter("@PageIndex", SqlDbType.Int);
paramPageIndex.Value = Convert.ToInt32(pageIndex);
command.Parameters.Add(paramPageIndex);
SqlParameter paramColumnName = new SqlParameter("@SortColumnName", SqlDbType.VarChar, 50);
paramColumnName.Value = sortColumnName;
command.Parameters.Add(paramColumnName);
SqlParameter paramSortorderBy = new SqlParameter("@SortOrderBy", SqlDbType.VarChar, 4);
paramSortorderBy.Value = sortOrderBy;
command.Parameters.Add(paramSortorderBy);
SqlParameter paramNumberOfRows = new SqlParameter("@NumberOfRows", SqlDbType.Int);
paramNumberOfRows.Value = Convert.ToInt32(numberOfRows);
command.Parameters.Add(paramNumberOfRows);
SqlParameter paramTotalRecords = new SqlParameter("@TotalRecords", SqlDbType.Int);
totalRecords = 0;
paramTotalRecords.Value = totalRecords;
paramTotalRecords.Direction = ParameterDirection.Output;
command.Parameters.Add(paramTotalRecords);
connection.Open();
using (SqlDataReader dataReader = command.ExecuteReader())
{
User user;
while (dataReader.Read())
{
user = new User();
user.ApplicationNo =Convert.ToString(dataReader["cApplicationNo"]);
user.FirstName = Convert.ToString(dataReader["cFirstName"]);
user.MiddleName = Convert.ToString(dataReader["cMiddleName"]);
user.LastName = Convert.ToString(dataReader["cLastName"]);
users.Add(user);
}
}
//totalRecords =(int)(paramTotalRecords.Value);
// totalRecords = 0;
}
return users;
}
}
public bool IsReusable
{
get
{
return false;
}
}
}
}
有人可以帮我解决这个问题, 欢迎任何建议,谢谢
答案 0 :(得分:6)
在您的问题中,您主要使用the demo project中的old answer。所有其他后来的答案显示了如何在服务器上实现高级搜索,分页和排序(例如this one或this one)我使用了更新的ASP.NET技术,主要是ASP.NET MVC。另一方面,演示代码可以在以下部分中决定:
page
,rows
,sidx
,sord
,_search
,filters
。可以使用jqGrid的prmNames
选项重命名参数。SqlCommand
和SqlDataReader
。loadError
回调中的客户端代码应该解码错误信息并以某种形式显示它。如果使用ASP.NET MVC,我在the answer中显示了如何实现HandleJsonExceptionAttribute
属性,该属性可用作[HandleJsonException]
而不是标准[HandleError]
。如果使用WCF,可以使用WebFaultException<string>
(请参阅here)。对于通用ASHX处理程序,可以使用Application_Error
Global.asax
用于此目的。If-None-Match
部分发送到服务器,该服务器包含来自先前服务器响应的ETag
。服务器可以验证自上次响应以来服务器数据是否已更改。最后,服务器将返回新的JSON数据或空响应,该响应允许客户端使用旧响应中的数据。我做了the demo project,展示了上述所有步骤。它包含一个小型数据库,我填写了一些着名数学家的信息。演示显示网格 可以使用排序,分页,工具栏过滤或高级搜索。如果出现某些错误(例如,如果停止Windows服务“SQL Server(SQLEXPRESS)”),您将看到如下错误消息:
在演示中实现ASHX句柄的C#代码是
using System;
using System.Globalization;
using System.Net;
using System.Security.Cryptography;
using System.Text;
using System.Web;
using Newtonsoft.Json;
namespace jqGridASHX {
// ReSharper disable InconsistentNaming
public class jqGridData : IHttpHandler {
// ReSharper restore InconsistentNaming
public void ProcessRequest (HttpContext context) {
// to be able to use context.Response.Cache.SetETag later we need the following:
context.Response.Cache.SetCacheability(HttpCacheability.ServerAndPrivate);
// to use with HTTP GET we want be sure that caching of data work correct
// so we request revalidation of data by setting in HTTP header the line
// "Cache-Control: private, max-age=0"
context.Response.Cache.SetMaxAge (new TimeSpan (0));
string numberOfRows = context.Request["rowsPerPage"];
int nRows, iPage;
if (String.IsNullOrEmpty (numberOfRows) || !int.TryParse (numberOfRows, NumberStyles.Integer, CultureInfo.InvariantCulture, out nRows))
nRows = 10; // default value
string pageIndex = context.Request["pageIndex"];
if (String.IsNullOrEmpty(pageIndex) || !int.TryParse(pageIndex, NumberStyles.Integer, CultureInfo.InvariantCulture, out iPage))
iPage = 10; // default value
string sortColumnName = context.Request["sortByColumn"];
string sortOrder = context.Request["sortOrder"];
string search = context.Request["isSearching"];
string filters = context.Request["filters"];
// we can use high-performance Newtonsoft.Json
string str = JsonConvert.SerializeObject (
MyData.GetDataForJqGrid (
nRows, iPage, sortColumnName,
!String.IsNullOrEmpty (sortOrder) &&
String.Compare (sortOrder, "desc", StringComparison.Ordinal) == 0
? MyData.SortOrder.Desc
: MyData.SortOrder.Asc,
search != null && String.Compare (search, "true", StringComparison.Ordinal) == 0,
filters));
context.Response.ContentType = "application/json";
// calculate MD5 from the returned data and use it as ETag
byte[] hash = MD5.Create().ComputeHash(Encoding.ASCII.GetBytes(str));
string newETag = Convert.ToBase64String(hash);
// compare ETag of the data which already has the client with ETag of response
string incomingEtag = context.Request.Headers["If-None-Match"];
if (String.Compare(incomingEtag, newETag, StringComparison.Ordinal) == 0)
{
// we don't need return the data which the client already have
context.Response.SuppressContent = true;
context.Response.StatusCode = (int)HttpStatusCode.NotModified;
return;
}
context.Response.Cache.SetETag(newETag);
context.Response.Write(str);
}
public bool IsReusable {
get { return false; }
}
}
}
它使用Newtonsoft.Json
进行JSON序列化,并将MD5哈希值用作ETag
。
方法MyData.GetDataForJqGrid
提供数据库中的数据。在演示中,我主要使用the answer中的代码,因此我使用Entity Framework来访问数据库:
using System;
using System.Data.Objects;
using System.Globalization;
using System.Linq;
using Newtonsoft.Json;
namespace jqGridASHX
{
public static class MyData
{
public enum SortOrder {
Asc,
Desc
}
public static Object GetDataForJqGrid(int nRows, int iPage,
string sortColumnName, SortOrder sortOrder,
bool isSearch, string filters)
{
var context = new MyDatabaseEntities();
var f = (!isSearch || string.IsNullOrEmpty(filters)) ? null : JsonConvert.DeserializeObject<Filters>(filters);
ObjectQuery<User> filteredQuery =
f == null ? context.Users : f.FilterObjectSet(context.Users);
filteredQuery.MergeOption = MergeOption.NoTracking; // we don't want to update the data
var totalRecords = filteredQuery.Count();
var pagedQuery =
filteredQuery.Skip(
"it." + (String.IsNullOrEmpty(sortColumnName) ? "Id" : sortColumnName) + " " + sortOrder,
"@skip",
new ObjectParameter("skip", (iPage - 1) * nRows))
.Top("@limit", new ObjectParameter("limit", nRows));
// to be able to use ToString() below which is NOT exist in the LINQ to Entity
// we should include in queryDetails only the properies which we will use below
var queryDetails = (from item in pagedQuery
select new {
item.Id, item.FirstName, item.LastName, item.Birthday
}).ToArray();
return new {
total = (totalRecords + nRows - 1) / nRows,
page = iPage,
records = totalRecords,
rows = (from item in queryDetails
select new[] {
// In the demo we send Id as the 4-th element of row array.
// The value will be not displayed in the grid, but used as rowid
// (the id attribute of the <tr> in the <table>)
item.FirstName,
item.LastName,
item.Birthday == null? String.Empty : ((DateTime)item.Birthday).ToString("yyyy-MM-dd"),
item.Id.ToString (CultureInfo.InvariantCulture)
}).ToArray()
};
}
}
}
班级Filters
using System;
using System.Collections.Generic;
using System.Data.Objects;
using System.Text;
namespace jqGridASHX
{
public class Filters
{
// ReSharper disable InconsistentNaming
public enum GroupOp
{
AND,
OR
}
public enum Operations
{
eq, // "equal"
ne, // "not equal"
lt, // "less"
le, // "less or equal"
gt, // "greater"
ge, // "greater or equal"
bw, // "begins with"
bn, // "does not begin with"
//in, // "in"
//ni, // "not in"
ew, // "ends with"
en, // "does not end with"
cn, // "contains"
nc // "does not contain"
}
public class Rule
{
public string field { get; set; }
public Operations op { get; set; }
public string data { get; set; }
}
public GroupOp groupOp { get; set; }
public List<Rule> rules { get; set; }
// ReSharper restore InconsistentNaming
private static readonly string[] FormatMapping = {
"(it.{0} = @p{1})", // "eq" - equal
"(it.{0} <> @p{1})", // "ne" - not equal
"(it.{0} < @p{1})", // "lt" - less than
"(it.{0} <= @p{1})", // "le" - less than or equal to
"(it.{0} > @p{1})", // "gt" - greater than
"(it.{0} >= @p{1})", // "ge" - greater than or equal to
"(it.{0} LIKE (@p{1}+'%'))", // "bw" - begins with
"(it.{0} NOT LIKE (@p{1}+'%'))", // "bn" - does not begin with
"(it.{0} LIKE ('%'+@p{1}))", // "ew" - ends with
"(it.{0} NOT LIKE ('%'+@p{1}))", // "en" - does not end with
"(it.{0} LIKE ('%'+@p{1}+'%'))", // "cn" - contains
"(it.{0} NOT LIKE ('%'+@p{1}+'%'))" //" nc" - does not contain
};
internal ObjectQuery<T> FilterObjectSet<T>(ObjectQuery<T> inputQuery) where T : class
{
if (rules.Count <= 0)
return inputQuery;
var sb = new StringBuilder();
var objParams = new List<ObjectParameter>(rules.Count);
foreach (var rule in rules)
{
var propertyInfo = typeof(T).GetProperty(rule.field);
if (propertyInfo == null)
continue; // skip wrong entries
if (sb.Length != 0)
sb.Append(groupOp);
var iParam = objParams.Count;
sb.AppendFormat(FormatMapping[(int)rule.op], rule.field, iParam);
ObjectParameter param;
switch (propertyInfo.PropertyType.FullName)
{
case "System.Int32": // int
param = new ObjectParameter("p" + iParam, Int32.Parse(rule.data));
break;
case "System.Int64": // bigint
param = new ObjectParameter("p" + iParam, Int64.Parse(rule.data));
break;
case "System.Int16": // smallint
param = new ObjectParameter("p" + iParam, Int16.Parse(rule.data));
break;
case "System.SByte": // tinyint
param = new ObjectParameter("p" + iParam, SByte.Parse(rule.data));
break;
case "System.Single": // Edm.Single, in SQL: float
param = new ObjectParameter("p" + iParam, Single.Parse(rule.data));
break;
case "System.Double": // float(53), double precision
param = new ObjectParameter("p" + iParam, Double.Parse(rule.data));
break;
case "System.Boolean": // Edm.Boolean, in SQL: bit
param = new ObjectParameter("p" + iParam,
String.Compare(rule.data, "1", StringComparison.Ordinal) == 0 ||
String.Compare(rule.data, "yes", StringComparison.OrdinalIgnoreCase) == 0 ||
String.Compare(rule.data, "true", StringComparison.OrdinalIgnoreCase) == 0);
break;
default:
// TODO: Extend to other data types
// binary, date, datetimeoffset,
// decimal, numeric,
// money, smallmoney
// and so on.
// Below in the example for DateTime and the nullable DateTime
if (String.Compare(propertyInfo.PropertyType.FullName, typeof(DateTime?).FullName, StringComparison.Ordinal) == 0 ||
String.Compare(propertyInfo.PropertyType.FullName, typeof(DateTime).FullName, StringComparison.Ordinal) == 0)
{
// we use below en-US locale directly
param = new ObjectParameter("p" + iParam, DateTime.Parse(rule.data, new CultureInfo("en-US"), DateTimeStyles.None));
}
else {
param = new ObjectParameter("p" + iParam, rule.data);
}
break;
}
objParams.Add(param);
}
var filteredQuery = inputQuery.Where(sb.ToString());
foreach (var objParam in objParams)
filteredQuery.Parameters.Add(objParam);
return filteredQuery;
}
}
}
Global.asax.cs
的代码是
using System;
using System.Collections.Generic;
using System.Net;
using System.Reflection;
using System.Web;
using Newtonsoft.Json;
namespace jqGridASHX
{
internal class ExceptionInformation
{
public string Message { get; set; }
public string Source { get; set; }
public string StackTrace { get; set; }
public string ErrorCode { get; set; }
}
public class Global : HttpApplication
{
protected void Application_Error(object sender, EventArgs e)
{
if (Request.ContentType.Contains("application/json"))
{
Response.Clear();
Response.StatusCode = (int)HttpStatusCode.InternalServerError;
Response.Cache.SetMaxAge(new TimeSpan(0));
Response.ContentType = "application/json";
var exInfo = new List<ExceptionInformation>();
for (var ex = Server.GetLastError(); ex != null; ex = ex.InnerException) {
PropertyInfo propertyInfo = ex.GetType().GetProperty ("HResult");
exInfo.Add (new ExceptionInformation {
Message = ex.Message,
Source = ex.Source,
StackTrace = ex.StackTrace,
ErrorCode = propertyInfo != null && propertyInfo.GetValue (ex, null) is int
? "0x" + ((int)propertyInfo.GetValue (ex, null)).ToString("X")
: String.Empty
});
}
Response.Write(JsonConvert.SerializeObject(exInfo));
Context.Server.ClearError();
}
}
}
}
在客户端,我使用纯HTML页面来显示您可以在任何项目包含Web表单项目中包含该解决方案。该页面包含以下代码
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<title>https://stackoverflow.com/q/10698254/315935</title>
<meta charset="UTF-8" />
<link rel="stylesheet" href="Content/themes/redmond/jquery-ui.css" />
<link rel="stylesheet" href="Scripts/jqGrid/4.3.3/ui.jqgrid.css" />
<link rel="stylesheet" href="Content/Site.css" />
<script src="Scripts/jquery-1.7.2.min.js" type="text/javascript"></script>
<script src="Scripts/jquery-ui-1.8.20.min.js" type="text/javascript"></script>
<script src="Scripts/jqGrid/4.3.3/i18n/grid.locale-en.js" type="text/javascript"></script>
<script type="text/javascript">
$.jgrid.no_legacy_api = true;
$.jgrid.useJSON = true;
</script>
<script src="Scripts/jqGrid/4.3.3/jquery.jqGrid.min.js" type="text/javascript"></script>
<script src="Scripts/json2.min.js" type="text/javascript"></script>
<script src="Scripts/Common.js" type="text/javascript"></script>
<script src="Scripts/MyPage.js" type="text/javascript"></script>
</head>
<body>
<table id="list"><tr><td></td></tr></table>
<div id="pager"></div>
</body>
</html>
其中MyPage.js
是
/// <reference path="jquery-1.7.2.js" />
/// <reference path="jqGrid/4.3.3/i18n/grid.locale-en.js" />
/// <reference path="jqGrid/4.3.3/jquery.jqGrid.src.js" />
/// <reference path="Common.js" />
$(function () {
"use strict";
$("#list").jqGrid({
url: "jqGridData.ashx",
colNames: ["First Name", "Last Name", "Birthday"],
colModel: [
{ name: "FirstName", width: 200 },
{ name: "LastName", width: 180 },
{ name: "Birthday", width: 100, formatter: "date", align: "center",
searchoptions: { sopt: ["eq", "ne", "lt", "le", "gt", "ge"], dataInit: function (elem) {
$(elem).datepicker({
dateFormat: "m/d/yy",
minDate: "1/1/1753",
defaultDate: "4/30/1777",
autoSize: true,
changeYear: true,
changeMonth: true,
showButtonPanel: true,
showWeek: true
});
}}
}
],
jsonReader: {
cell: "",
// The Id value will be sent as the 4-th element of row array.
// The value will be not displayed in the grid, but used as rowid
// (the id attribute of the <tr> in the <table>)
id: "3"
},
rowNum: 10,
rowList: [10, 20, 30],
pager: "#pager",
rownumbers: true,
viewrecords: true,
sortname: "Birthday",
sortorder: "desc",
caption: "Famous Mathematicians"
}).jqGrid("navGrid", "#pager", { edit: false, add: false, del: false })
.jqGrid('filterToolbar', { stringResult: true, searchOnEnter: true, defaultSearch: "cn" });
});
和Common.js
:
/// <reference path="jquery-1.7.2.js" />
/// <reference path="jqGrid/4.3.3/i18n/grid.locale-en.js" />
/// <reference path="jqGrid/4.3.3/jquery.jqGrid.src.js" />
$.extend($.jgrid.defaults, {
height: "100%",
altRows: true,
altclass: "myAltRowClass",
shrinkToFit: false,
gridview: true,
rownumbers: true,
viewrecords: true,
datatype: "json",
sortable: true,
scrollrows: true,
headertitles: true,
loadui: "block",
viewsortcols: [false, "vertical", true],
prmNames: { nd: null, page: "pageIndex", rows: "rowsPerPage", sort: "sortByColumn", order: "sortOrder", search: "isSearching" },
ajaxGridOptions: { contentType: "application/json" },
ajaxRowOptions: { contentType: "application/json", type: "PUT", async: true },
ajaxSelectOptions: { contentType: "application/json", dataType: "JSON" },
serializeRowData: function (data) {
var propertyName, propertyValue, dataToSend = {};
for (propertyName in data) {
if (data.hasOwnProperty(propertyName)) {
propertyValue = data[propertyName];
if ($.isFunction(propertyValue)) {
dataToSend[propertyName] = propertyValue();
} else {
dataToSend[propertyName] = propertyValue;
}
}
}
return JSON.stringify(dataToSend);
},
resizeStop: function () {
var $grid = $(this.bDiv).find('>:first-child>.ui-jqgrid-btable:last-child'),
shrinkToFit = $grid.jqGrid('getGridParam', 'shrinkToFit'),
saveState = $grid.jqGrid('getGridParam', 'saveState');
$grid.jqGrid('setGridWidth', this.newWidth, shrinkToFit);
if ($.isFunction(saveState)) {
saveState.call($grid[0]);
}
},
gridComplete: function () {
$("#" + this.id + "_err").remove();
},
loadError: function (xhr) {
var response = xhr.responseText, errorDetail, errorHtml, i, l, errorDescription;
if (response.charAt(0) === '[' && response.charAt(response.length - 1) === ']') {
errorDetail = $.parseJSON(xhr.responseText);
var errorText = "";
for (i = 0, l = errorDetail.length; i < l; i++) {
if (errorText.length !== 0) {
errorText += "<hr/>";
}
errorDescription = errorDetail[i];
errorText += "<strong>" + errorDescription.Source + "</strong>";
if (errorDescription.ErrorCode) {
errorText += " (ErrorCode: " + errorDescription.ErrorCode + ")";
}
errorText += ": " + errorDescription.Message;
}
errorHtml = '<div id="errdiv" class="ui-state-error ui-corner-all" style="padding-left: 10px; padding-right: 10px; max-width:' +
($(this).closest(".ui-jqgrid").width() - 20) +
'px;"><p><span class="ui-icon ui-icon-alert" style="float: left; margin-right: .3em;"></span><span>' +
errorText + '</span></p></div>';
$("#" + this.id + "_err").remove();
$(this).closest(".ui-jqgrid").before(errorHtml);
}
}
});
$.extend($.jgrid.search, {
multipleSearch: true,
recreateFilter: true,
closeOnEscape: true,
searchOnEnter: true,
overlay: 0
});
更新:我做了一些小改进:包括json2.js(请参阅here)以支持旧版网络浏览器中的JSON.stringify
,修复日期的固定格式jQuery UI Datepicker,并在类DateType
中包含对DateType?
和System.Nullable<DateType>
(Filters
)的支持。因此,您可以从the same location下载项目的当前版本。