如何在jqGrid中实现多个搜索

Pri*_*tel 2 asp.net webforms ashx jqgrid

我有一个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>
Run Code Online (Sandbox Code Playgroud)

这是我的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;
            }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

有人可以帮我解决这个问题,欢迎任何建议,谢谢

Ole*_*leg 6

在您的问题中,您主要使用我的旧答案中的演示项目.所有其他后来的答案显示了如何在服务器上实现高级搜索,分页和排序(例如这一个这个)我使用了更新的ASP.NET技术,主要是ASP.NET MVC.另一方面,演示代码可以在以下部分中决定:

  1. 提供一些接口的服务器代码,jqGrid可以使用它来获取JSON响应.它可以是ASP.NET MVC控制器操作,WFC方法,ASMX Web服务的WebMethod或您使用的General ASHX Handler.
  2. 分析jqGrid发送的输入参数的服务器代码.该参数的默认名称为page,rows,sidx,sord,_search,filters.可以使用prmNamesjqGrid选项重命名参数.
  3. 访问数据库.服务器代码的一部分取决于您使用的技术.它可以是例如实体框架,LINQ to SQL的以上旧的,但具有良好的性能SqlCommandSqlDataReader.
  4. Encoding of results as JSON. One can use for example standard JavaScriptSerializer or DataContractJsonSerializer or high-performance JSON framework Json.NET (knows as Newtonsoft.JSON). Microsoft uses and supports the open source Json.NET serializer in the new version of ASP.NET MVC 4.0 and ASP.NET Web API. One can include Json.NET in the ASP.NET project and can update it to the last recent version using NuGet.
  5. 在服务器上处理异常并以JSON格式向客户端(jqGrid)报告错误信息.代码有点不同,取决于服务器上使用的技术.loadErrorjqGrid回调中的客户端代码应该解码错误信息并以某种形式显示它.在使用ASP.NET MVC的情况下我在答案中显示如何实现HandleJsonExceptionAttribute可以用作[HandleJsonException]标准而不是标准的属性[HandleError].如果使用WCF,可以使用WebFaultException<string>(见这里).一般来说ASHX处理程序的情况下,可以使用Application_ErrorGlobal.asax为宗旨.
  6. Optionally one can includes in the server code setting of ETag in the HTTP header. It allows to control client side cache on the server side. If the client need JSON data previously returned from the server it will automatically send If-None-Match part in the HTTP request to the server which contain ETag from the previous server response. The server can verify whether the server data are changed since the last response. At the end the server will either returns the new JSON data or an empty response which allows the client to use the data from the old response.
  7. One need to write JavaScript code which create jqGrid.

I made the demo project which demonstrate all the above steps. It contains small Database which I fill with information about some from the famous mathematicians. The demo display the grid enter image description here where one can use sorting, paging, toolbar filtering or advanced searching. In case of some error (for example if you stop Windows Service "SQL Server (SQLEXPRESS)") you will see the error message like the following: enter image description here

The C# code which implements ASHX handle in the demo is

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; }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

It uses Newtonsoft.Json for JSON serialization and uses MD5 hash as ETag.

The method MyData.GetDataForJqGrid provide the data from the database. In the demo I use mainly the code from the answer, so I use Entity Framework to access the database:

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()
            };
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

where the class 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;
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

The code from Global.asax.cs is

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();
            }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

On the client side I used pure HTML page to show mostly clear that you can include the solution in any your project inclusive Web Form project. The page has the following code

<!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>
Run Code Online (Sandbox Code Playgroud)

where MyPage.js is

/// <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" });
});
Run Code Online (Sandbox Code Playgroud)

and 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
});
Run Code Online (Sandbox Code Playgroud)

UPDATED: I made some small improvements: included json2.js (see here) to support JSON.stringify in old web browsers, fixed format of date in the jQuery UI Datepicker and included support for DateType and DateType? (System.Nullable<DateType>) in the class Filters. So you can download the current version of the project from the same location.