jqgrid与asp.net webmethod和json使用排序,分页,搜索和LINQ – 但需要动态运算符

这个工作! ..但还需要一个东西…

好吧,所以这是一个“评论”和问题。首先,是可以帮助其他人搜索asp.net webmethod / jqGrid方法的工作示例。下面的代码完全工作,发送/接收JSON参数从和到jqGrid为了有正确的分页,排序,过滤(使用单一搜索)利用LINQ ..它使用片段从这里和那里…

第二,是我的问题:
有没有人确定一个适当的方法来计算发送到codebehind的动态运算符?由于客户端可能发送“eq”(等于),“cn”(包含)“gt”(大于),我需要一个更好的方式动态生成一个whereclause,不仅限于我构建一个whereclause字符串“=”或“<>”,而是可以包括与动态Linq利用.Contains或.EndsWith等的能力。

我可能需要某种谓词构建器函数。

代码,处理此截至现在(它的工作,但是有限):

if (isSearch) {
    searchOper = getOperator(searchOper); // need to associate correct operator to value sent from jqGrid
    string whereClause = String.Format("{0} {1} {2}",searchField,searchOper,"@" + searchField);

    //--- associate value to field parameter
    Dictionary<string,object> param = new Dictionary<string,object>();
    param.Add("@" + searchField,searchString);

    query = query.Where(whereClause,new object[1] { param });
}

随着节目………

==================================================

首先,JAVASCRIPT

<script type="text/javascript">
$(document).ready(function() {

    var grid = $("#grid");

    $("#grid").jqGrid({
        // setup custom parameter names to pass to server
        prmNames: { 
            search: "isSearch",nd: null,rows: "numRows",page: "page",sort: "sortField",order: "sortOrder"
        },// add by default to avoid webmethod parameter conflicts
        postData: { searchString: '',searchField: '',searchOper: '' },// setup ajax call to webmethod
        datatype: function(postdata) {    
            $(".loading").show(); // make sure we can see loader text
            $.ajax({
                url: 'PageName.aspx/getGridData',type: "POST",contentType: "application/json; charset=utf-8",data: JSON.stringify(postdata),dataType: "json",success: function(data,st) {
                    if (st == "success") {
                        var grid = $("#grid")[0];
                        grid.addJSONData(JSON.parse(data.d));
                    }
                },error: function() {
                    alert("Error with AJAX callback");
                }
            }); 
        },// this is what jqGrid is looking for in json callback
        jsonReader: {  
            root: "rows",total: "totalpages",records: "totalrecords",cell: "cell",id: "id",//index of the column with the PK in it 
            userdata: "userdata",repeatitems: true
        },colNames: ['Id','First Name','Last Name'],colModel: [
            { name: 'id',index: 'id',width: 55,search: false },{ name: 'fname',index: 'fname',width: 200,searchoptions: { sopt: ['eq','ne','cn']} },{ name: 'lname',index: 'lname','cn']} }
        ],rowNum: 10,rowList: [10,20,30],pager: jQuery("#pager"),sortname: "fname",sortorder: "asc",viewrecords: true,caption: "Grid Title Here",gridComplete: function() {
        $(".loading").hide();
    }
    }).jqGrid('navGrid','#pager',{ edit: false,add: false,del: false },{},// default settings for edit
    {},// add
    {},// delete
    { closeOnEscape: true,closeAfterSearch: true},//search
    {}
)
});
</script>

==================================================

第二,C#WEBMETHOD

[WebMethod]
public static string getGridData(int? numRows,int? page,string sortField,string sortOrder,bool isSearch,string searchField,string searchString,string searchOper) {
    string result = null;

    MyDataContext db = null;
    try {
        //--- retrieve the data
        db = new MyDataContext("my connection string path");  
        var query = from u in db.TBL_USERs
                    select new User {
                        id = u.REF_ID,lname = u.LAST_NAME,fname = u.FIRST_NAME
                    };

        //--- determine if this is a search filter
        if (isSearch) {
            searchOper = getOperator(searchOper); // need to associate correct operator to value sent from jqGrid
            string whereClause = String.Format("{0} {1} {2}","@" + searchField);

            //--- associate value to field parameter
            Dictionary<string,object>();
            param.Add("@" + searchField,searchString);

            query = query.Where(whereClause,new object[1] { param });
        }

        //--- setup calculations
        int pageIndex = page ?? 1; //--- current page
        int pageSize = numRows ?? 10; //--- number of rows to show per page
        int totalRecords = query.Count(); //--- number of total items from query
        int totalPages = (int)Math.Ceiling((decimal)totalRecords / (decimal)pageSize); //--- number of pages

        //--- filter dataset for paging and sorting
        IQueryable<User> orderedRecords = query.OrderBy(sortfield);
        IEnumerable<User> sortedRecords = orderedRecords.ToList();
        if (sortorder == "desc") sortedRecords= sortedRecords.Reverse();
        sortedRecords = sortedRecords
          .Skip((pageIndex - 1) * pageSize) //--- page the data
          .Take(pageSize);

        //--- format json
        var jsonData = new {
            totalpages = totalPages,//--- number of pages
            page = pageIndex,//--- current page
            totalrecords = totalRecords,//--- total items
            rows = (
                from row in sortedRecords
                select new {
                    i = row.id,cell = new string[] {
                        row.id.ToString(),row.fname,row.lname 
                    }
                }
           ).ToArray()
        };

        result = Newtonsoft.Json.JsonConvert.SerializeObject(jsonData);

    } catch (Exception ex) {
        Debug.WriteLine(ex);
    } finally {
        if (db != null) db.Dispose();
    }

    return result;
}

/* === User Object =========================== */
public class User {
    public int id { get; set; }
    public string lname { get; set; }
    public string fname { get; set; }
}

==================================================

第三,事实

>为了在LINQ中有动态的OrderBy子句,我不得不把一个类拖到我的AppCode文件夹,名为’Dynamic.cs’。您可以从downloading here检索文件。您将在“DynamicQuery”文件夹中找到该文件。该文件将使您能够使用动态ORDERBY子句,因为我们不知道除了初始加载之外,我们要过滤的列。
>为了将JSON从C-sharp序列化到JS,我引入了位于这里的James Newton-King JSON.net DLL:下载后,有一个“Newtonsoft.Json.Compact.dll”,您可以添加在您的Bin文件夹中作为参考
>这是我的USING的块
使用系统;
使用System.Collections;
使用System.Collections.Generic;
使用System.Linq;
使用System.Web.UI.WebControls;
使用System.Web.Services;
使用System.Linq.Dynamic;
>对于Javascript引用,我使用以下脚本各自的顺序,以便帮助一些人:1)jquery-1.3.2.min.js … 2)jquery-ui-1.7.2.custom.min .js … 3)json.min.js … 4)i18n / grid.locale-en.js … 5)jquery.jqGrid.min.js
>对于CSS,我使用jqGrid的必需品以及jQuery UI主题:1)jquery_theme / jquery-ui-1.7.2.custom.css … 2)ui.jqgrid.css

将参数从JS获取到WebMethod的关键,而不必解析后端的非序列化字符串或者必须设置一些JS逻辑来切换不同数量的参数的方法是这个块

postData: { searchString: '',

当您实际执行搜索时,这些参数仍将正确设置,然后在“重置”或希望网格不进行任何过滤时将其重置为空

希望这有助于其他人!并且感谢您有时间阅读和回复关于在运行时与操作符构建whereclause的动态方法

解决方法

考虑这个扩展方法,将字符串转换为MemberExpression:
public static class StringExtensions
{
    public static MemberExpression ToMemberExpression(this string source,ParameterExpression p)
    {
        if (p == null)
            throw new ArgumentNullException("p");

        string[] properties = source.Split('.');

        Expression expression = p;
        Type type = p.Type;

        foreach (var prop in properties)
        {
            var property = type.GetProperty(prop);
            if (property == null)
                throw new ArgumentException("Invalid expression","source");

            expression = Expression.MakeMemberAccess(expression,property);
            type = property.PropertyType;
        }

        return (MemberExpression)expression;
    }
}

下面的方法将您拥有的字符串转换为Lambda表达式,您可以使用它来过滤Linq查询。它是一个通用的方法,用T作为域实体。

public virtual Expression<Func<T,bool>> CreateExpression<T>(string searchField,string searchOper)
    {
        Expression exp = null;
        var p = Expression.Parameter(typeof(T),"p");

        try
        {
            Expression propertyAccess = searchField.ToExpression(p);

            switch (searchOper)
            {
                case "bw":
                    exp = Expression.Call(propertyAccess,typeof(string).GetMethod("StartsWith",new Type[] { typeof(string) }),Expression.Constant(searchString));
                    break;
                case "cn":
                    exp = Expression.Call(propertyAccess,typeof(string).GetMethod("Contains",Expression.Constant(searchString));
                    break;
                case "ew":
                    exp = Expression.Call(propertyAccess,typeof(string).GetMethod("EndsWith",Expression.Constant(searchString));
                    break;
                case "gt":
                    exp = Expression.GreaterThan(propertyAccess,Expression.Constant(searchString,propertyAccess.Type));
                    break;
                case "ge":
                    exp = Expression.GreaterThanOrEqual(propertyAccess,propertyAccess.Type));
                    break;
                case "lt":
                    exp = Expression.LessThan(propertyAccess,propertyAccess.Type));
                    break;
                case "le":
                    exp = Expression.LessThanOrEqual(propertyAccess,propertyAccess.Type));
                    break;
                case "eq":
                    exp = Expression.Equal(propertyAccess,Expression.Constant(searchString.ToType(propertyAccess.Type),propertyAccess.Type));
                    break;
                case "ne":
                    exp = Expression.NotEqual(propertyAccess,propertyAccess.Type));
                    break;
                default:
                    return null;
            }

            return (Expression<Func<T,bool>>)Expression.Lambda(exp,p);
        }
        catch
        {
            return null;
        }
    }

所以,你可以这样使用它:

db.TBL_USERs.Where(CreateExpression<TBL_USER>("LAST_NAME","Costa","eq"));

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


引言 本文从Linux小白的视角, 在CentOS 7.x服务器上搭建一个Nginx-Powered AspNet Core Web准生产应用。 在开始之前,我们还是重温一下部署原理,正如你所常见的.Net Core 部署图: 在Linux上部署.Net Core App最好的方式是在Linux机器
引言: 多线程编程/异步编程非常复杂,有很多概念和工具需要去学习,贴心的.NET提供Task线程包装类和await/async异步编程语法糖简化了异步编程方式。 相信很多开发者都看到如下异步编程实践原则: 遵守以上冷冰冰的②③条的原则,可保证异步程序按照预期状态正常运作;我们在各大编程论坛常看到违背
一. 宏观概念 ASP.NET Core Middleware是在应用程序处理管道pipeline中用于处理请求和操作响应的组件。 每个组件是pipeline 中的一环。 自行决定是否将请求传递给下一个组件 在处理管道的下个组件执行之前和之后执行业务逻辑 二. 特性和行为 ASP.NET Core处
背景 在.Net和C#中运行异步代码相当简单,因为我们有时候需要取消正在进行的异步操作,通过本文,可以掌握 通过CancellationToken取消任务(包括non-cancellable任务)。 Task&#160;表示无返回值的异步操作, 泛型版本Task&lt;TResult&gt;表示有返
HTTP基本认证 在HTTP中,HTTP基本认证(Basic Authentication)是一种允许网页浏览器或其他客户端程序以(用户名:口令) 请求资源的身份验证方式,不要求cookie,session identifier、login page等标记或载体。 - 所有浏览器据支持HTTP基本认
1.Linq 执行多列排序 OrderBy的意义是按照指定顺序排序,连续两次OrderBy,后面一个有可能会打乱前面一个的排序顺序,可能与预期不符。 要实现sql中的order by word,name类似效果; LINQ 有ThenBy可以紧接使用, ThenBy记住原本排序的值,然后再排其他值,
ASP.NET Core 核心特性:开源、跨平台、高性能是其决战JAVA的必胜法宝,最引人关注的跨平台特性 到底是怎么实现? &#xA; 本文分Unix、Windows剖析跨平台内幕,读完让你大呼过瘾。
前导 Asynchronous programming Model(APM)异步编程模型以BeginMethod(...) 和 EndMethod(...)结对出现。 IAsyncResult BeginGetResponse(AsyncCallback callback, object state
引言 最近在公司开发了一个项目,项目部署架构图如下: 思路 如图中文本所述,公司大数据集群不允许直接访问外网,需要一个网关服务器代理请求,本处服务器A就是边缘代理服务器的作用。 通常技术人员最快捷的思路是在服务器A上部署IISʺpplication Request Routing Module组件
作为一枚后端程序狗,项目实践常遇到定时任务的工作,最容易想到的的思路就是利用Windows计划任务/wndows service程序/Crontab程序等主机方法在主机上部署定时任务程序/脚本。 但是很多时候,若使用的是共享主机或者受控主机,这些主机不允许你私自安装exe程序、Windows服务程序
引言 熟悉TPL Dataflow博文的朋友可能记得这是个单体程序,使用TPL Dataflow 处理工作流任务, 在使用Docker部署的过程中, 有一个问题一直无法回避: 在单体程序部署的瞬间(服务不可用)会有少量流量无法处理;更糟糕的情况下,迭代部署的这个版本有问题,上线后无法运作, 更多的流
合格的web后端程序员,除搬砖技能,还必须会给各种web服务器配置Https,本文结合ASP.NET Core部署模型聊一聊启用Https的方式。 温故知新 目前常见的Http请求明文传输,请求可能被篡改,访问的站点可能被伪造。 HTTPS是HTTP加上TLS/SSL协议构建的可进行加密传输、身份认
长话短说 前文《解剖HttpClientFactory,自由扩展HttpMessageHandler》主要讲如何为HttpClientFactory自定义HttpMessageHandler组件, 现在来完成课后的小作业: 将重点日志字段显示到Nlog的LayoutRenderer上。 本文实现一个
引言问题 作为资深老鸟,有事没事,出去面试;找准差距、定位价值。 面试必谈哈希, Q1:什么是哈希? Q2:哈希为什么快? Q3:你是怎么理解哈希算法利用空间换取时间的? Q4:你是怎么解决哈希冲突的? Q5:你有实际用写过哈希算法吗? 知识储备 哈希(也叫散列)是一种查找算法(可用于插入),哈希算
前言 如题,有感于博客园最近多次翻车,感觉像胡子眉毛一把抓, 定位不了生产环境的问题。 抛开流程问题,思考在生产环境中如何做故障排除,&#160;发现博客园里面这方面的文章比较少。 .Net 本身是提供了sos.dll工具帮助我们在生产中故障排除,通过提供有关内部公共语言运行时(CLR)环境的信息,
.NET程序是基于.NET Framework、.NET Core、Mono、【.NET实现】开发和运行的 ,定义以上【.NET实现】的标准规范称为.NET Standard .NET Standard .NET标准是一组API集合,由上层三种【.NET实现】的Basic Class Library
长话短说 上个月公司上线了一个物联网数据科学项目,我主要负责前端接受物联网事件,并提供 参数下载。 webapp 部署在Azure云上,参数使用Azure SQL Server存储。 最近从灰度测试转向全量部署之后,日志时常收到: SQL Session超限报错。 排查 我在Azure上使用的是 S
临近年关,搜狗,360浏览器出现页面无法成功跳转,同域Cookie丢失? 也许是服务端 SameSite惹的祸。&#xA;本文揭示由于Chrome低版本内核不识别 SameSite= None, 引发的单点登录故障。
本文聊一聊TraceID的作用和一般组成,衍生出ASP. NETCore 单体和分布式程序中 TraceId 的使用方式
通过给 HttpClint请求的日志增加 TraceId,解锁自定义扩展 HttpClientFacroty 的姿势