MVC中灵活实现自定义查询分页之实践

注:文字写作是本人弱项,如描述有问题,请见谅!!!

前言:在开发中,经常使用查询分页,为了达到统一与复用,进行的统合实例,本实例将一步一步实现一个统合的查询分页的实现。

开发工具:VS2012

1.建立项目:

第一个是MVC4项目,第二个是一个类库
2.在类库PageSearchModel中添加引用如下:

3.要进行查询,我们添加一个查询方法枚举:QueryMethod.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace System.Web.Mvc
{
    /// <summary>
    /// Html表单元素的检索方式
    /// </summary>
    public enum QueryMethod
    {
        /// <summary>
        /// 等于
        /// </summary>
        //[GlobalCode("=", OnlyAttribute = true)]
        Equal = 0,

        /// <summary>
        /// 小于
        /// </summary>
        //// [GlobalCode("<", OnlyAttribute = true)]
        LessThan = 1,

        /// <summary>
        /// 大于
        /// </summary>
        // [GlobalCode(">", OnlyAttribute = true)]
        GreaterThan = 2,

        /// <summary>
        /// 小于等于
        /// </summary>
        // [GlobalCode("<=", OnlyAttribute = true)]
        LessThanOrEqual = 3,

        /// <summary>
        /// 大于等于
        /// </summary>
        // [GlobalCode(">=", OnlyAttribute = true)]
        GreaterThanOrEqual = 4,

        /// <summary>
        /// Like
        /// </summary>
        // [GlobalCode("like", OnlyAttribute = true)]
        Like = 6,

        /// <summary>
        /// In
        /// </summary>
        // [GlobalCode("in", OnlyAttribute = true)]
        In = 7,

        /// <summary>
        /// 输入一个时间获取当前天的时间块操作, ToSql未实现,仅实现了IQueryable
        /// </summary>
        // [GlobalCode("between", OnlyAttribute = true)]
        DateBlock = 8,

        // [GlobalCode("<>", OnlyAttribute = true)]
        NotEqual = 9,


        // [GlobalCode("like", OnlyAttribute = true)]
        StartsWith = 10,

        // [GlobalCode("like", OnlyAttribute = true)]
        EndsWith = 11,

        /// <summary>
        /// 处理Like的问题
        /// </summary>
        [System.ComponentModel.EditorBrowsable(System.ComponentModel.EditorBrowsableState.Never)]
        Contains = 12,

        /// <summary>
        /// 处理In的问题
        /// </summary>
        [System.ComponentModel.EditorBrowsable(System.ComponentModel.EditorBrowsableState.Never)]
        StdIn = 13,

        /// <summary>
        /// 处理Datetime小于+23h59m59s999f的问题
        /// </summary>
        [System.ComponentModel.EditorBrowsable(System.ComponentModel.EditorBrowsableState.Never)]
        DateTimeLessThanOrEqual = 14
    }
}
View Code

4.添加一个排序类:QueryOrder.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace System.Web.Mvc
{
    public class QueryOrder
    {
        public QueryOrder()
        {
            Order = OrderType.ASC;
        }
        /// <summary>
        /// 排序字段
        /// </summary>
        public virtual string Field { get; set; }
        /// <summary>
        /// 排序方式
        /// </summary>
        public virtual OrderType Order { get; set; }

    }
    public enum OrderType
    {
        ASC,
        DESC
    }
}
View Code

5.添加一个组合查询条件类:ConditionItem.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Web.Mvc;

namespace System.Web.Mvc
{
    /// <summary>
    /// 用于存储查询条件的单元
    /// </summary>
    public class ConditionItem
    {
        public ConditionItem() { }

        public ConditionItem(string field, QueryMethod method, object val)
        {
            Field = field;
            Method = method;
            Value = val;
        }

        /// <summary>
        /// 字段
        /// </summary>
        public string Field { get; set; }

        /// <summary>
        /// 查询方式,用于标记查询方式HtmlName中使用[]进行标识
        /// </summary>
        public QueryMethod Method { get; set; }

        /// <summary>
        ////// </summary>
        public object Value { get; set; }

        /// <summary>
        /// 前缀,用于标记作用域,HTMLName中使用()进行标识
        /// </summary>
        public string Prefix { get; set; }

        /// <summary>
        /// 如果使用Or组合,则此组组合为一个Or序列
        /// </summary>
        public string OrGroup { get; set; }
    }
}
View Code

6.添加一个表格的列类:PageColum.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace System.Web.Mvc
{
    /// <summary>
    ////// </summary>
    public class PageColum
    {
        public PageColum()
        {
            Id = Guid.NewGuid().ToString();
            Sort = false;
        }
        /// <summary>
        /// 编号
        /// </summary>
        public string Id { get; set; }
        /// <summary>
        /// 字段
        /// </summary>
        public string Field { get; set; }
        /// <summary>
        /// 列头名
        /// </summary>
        public string Header { get; set; }
        /// <summary>
        /// 排序 DESC为true
        /// </summary>
        public bool Sort { get; set; }
        /// <summary>
        /// 列样式
        /// </summary>
        public string Style { get; set; }
    }
    /// <summary>
    ////// </summary>
    public class PageColum<T> : PageColum
    {
        public Func<T, object> Format { get; set; }
    }
}
View Code

7.添加一个表格的行类:PageRow.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace System.Web.Mvc
{
    /// <summary>
    ////// </summary>
    public class PageRow
    {
        public PageRow()
        {
            RowData = new List<RowItem>();
        }
        // <summary>
        /// 行数据
        /// </summary>
        public IList<RowItem> RowData { get; set; }
        /// <summary>
        /// 单行数据对象的主键字段名
        /// </summary>
        public string SourcePrimaryKey { get; set; }
        /// <summary>
        /// 行样式
        /// </summary>
        public string Style { get; set; }
    }
    /// <summary>
    /// 行中单列数据
    /// </summary>
    public class RowItem
    {
        /// <summary>
        /// 对应列编号
        /// </summary>
        public string ColumId { get; set; }
        /// <summary>
        /// 是否是字段列
        /// </summary>
        public bool CheckFieldColum { get; set; }
        /// <summary>
        ////// </summary>
        public object Vaule { get; set; }
    }
}
View Code

8.添加一个查询分页类:PageModel.cs

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Linq.Expressions;
using System.Reflection;
using System.Text;
using System.Web;
using System.Web.WebPages;

namespace System.Web.Mvc
{
    /// <summary>
    /// 分页模型
    /// </summary>
    public class PageModel
    {
        public PageModel()
        {
            this.PageIndex = 1;
            this.PageSize = 15;
            SearchQuery = new List<ConditionItem>();
            Id = Guid.NewGuid().ToString().Replace(@"/","").Replace(@"","").Replace("-", "_");
        }
        /// <summary>
        /// 页的唯一标识
        /// </summary>
        public virtual string Id { get; set; }
        /// <summary>
        /// 页码从1开始
        /// </summary>
        public virtual int PageIndex { get; set; }
        /// <summary>
        /// 每页显示数量
        /// </summary>
        public virtual int PageSize { get; set; }
        /// <summary>
        /// 页总数
        /// </summary>
        public virtual long PageTotal
        {
            get
            {
                #region
                if (DataTotal == 0)
                {
                    return 0;
                }
                else if (DataTotal <= PageSize)
                {
                    return 1;
                }
                else
                {
                    var z = DataTotal / PageSize;
                    var y = DataTotal % PageSize;
                    if (y != 0)
                    {
                        return z + 1;
                    }
                    else
                    {
                        return z;
                    }
                }
                #endregion
            }
        }
        /// <summary>
        /// 数据总数
        /// </summary>
        public virtual long DataTotal { get; set; }
        /// <summary>
        /// 查询条件
        /// </summary>
        public virtual List<ConditionItem> SearchQuery { get; set; }
        /// <summary>
        /// 排序
        /// </summary>
        public virtual QueryOrder Order { get; set; }
        /// <summary>
        /// 是否全选
        /// </summary>
        public bool SelectAll { get; set; }
        /// <summary>
        /// 选择的查询集合
        /// </summary>
        public IList<string> SelectPrimaryKeys { get; set; }



        /// <summary>
        /// 判断查询字段是存在
        /// </summary>
        /// <param name="expr"></param>
        /// <returns></returns>
        public bool CheckSearchName<T>(Expression<Func<T, object>> expr)
        {
            var field= expr.Body.ToString().Split('.').Last();
            if (SearchQuery.Where(m => m.Field == field).Count() > 0)
                return true;
            else
                return false;
        }
        /// <summary>
        /// 查询字段值
        /// </summary>
        /// <param name="expr"></param>
        /// <returns></returns>
        public object SearchValue<T>(Expression<Func<T, object>> expr)
        {
            var field = expr.Body.ToString().Split('.').Last();
            var data = this.SearchQuery.Where(m => m.Field == field);
            if (data.Count() > 0)
            {
                return data.First().Value;
            }
            return "";
        }
        /// <summary>
        /// 设置当前分页对象
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="data"></param>
        /// <param name="dataTotal"></param>
        /// <returns></returns>
        public PageModel<T> Record<T>(IEnumerable<T> data, long dataTotal = -1) where T : class
        {
            var model = new PageModel<T>(data, dataTotal);
            model.PageIndex = this.PageIndex;
            model.PageSize = this.PageSize;
            model.Order = this.Order;
            model.SearchQuery = this.SearchQuery;
            return model;
        }

    }
    /// <summary>
    /// 分页模型
    /// </summary>
    public class PageModel<T> : PageModel,IHtmlString  where T : class//,IHtmlString
    {
        public PageModel(IEnumerable<T> data, Int64 dataTotal = -1)
            : base()
        {
            #region 设置数据总数
            if (data != null)
                DataSource = data;
            else
                DataSource = new List<T>();
            if (dataTotal == -1)
            {
                if (data != null)
                {
                    DataTotal = data.Count();
                }
                else
                {
                    DataTotal = 0;
                }
            }
            else
            {
                DataTotal = dataTotal;
            }
            #endregion
            this.TableClassName = "baseui-table";
            Colums = new List<PageColum<T>>();
        }
        /// <summary>
        /// 数据源
        /// </summary>
        public virtual IEnumerable<T> DataSource { get; set; }
        /// <summary>
        /// 数据列
        /// </summary>
        private IList<PageColum<T>> Colums { get; set; }
        /// <summary>
        /// 数据的主键字段名
        /// </summary>
        private string SourcePrimaryKey { get; set; }
        /// <summary>
        /// 是否显示选择框
        /// </summary>
        private bool ShowCheckBox { get; set; }//显示选择框
        /// <summary>
        /// 列样式类名
        /// </summary>
        private string TableClassName { get; set; }
        /// <summary>
        /// 提交的表单ID
        /// </summary>
        private string SearchFormId { get; set; }
        /// <summary>
        /// 要查询的form表单ID
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public PageModel<T> SetSearchFormId(string id)
        {
            this.SearchFormId = id;
            return this;
        }
        /// <summary>
        /// 是否显示选择框
        /// </summary>
        /// <param name="show"></param>
        /// <returns></returns>
        public PageModel<T> SetShowCheckBox(bool show = false)
        {
            this.ShowCheckBox = show;
            return this;
        }
        /// <summary>
        /// 查询字段
        /// </summary>
        /// <param name="expr"></param>
        /// <returns></returns>
        public string SearchName(Expression<Func<T, object>> expr)
        {
            return expr.Body.ToString().Split('.').Last(); 
        }
        /// <summary>
        /// 查询字段值
        /// </summary>
        /// <param name="expr"></param>
        /// <returns></returns>
        public object SearchValue(Expression<Func<T, object>> expr)
        {
            var data = this.SearchQuery.Where(m => m.Field == SearchName(expr));
            if (data.Count() > 0)
            {
                return data.First().Value;
            }
            return "";
        }
        /// <summary>
        /// 设置数据源的每一行的主键字段
        /// </summary>
        /// <param name="expr"></param>
        /// <returns></returns>
        public PageModel<T> SetSourceKey(Expression<Func<T, object>> expr)
        {
            this.SourcePrimaryKey = expr.Body.ToString().Split('.').Last();
            return this;
        }
        /// <summary>
        /// 设置表的样式类
        /// </summary>
        /// <param name="className"></param>
        /// <returns></returns>
        public PageModel<T> SetClass(string className)
        {
            this.TableClassName = className;

            return this;
        }
        /// <summary>
        /// 设置显示列
        /// </summary>
        /// <param name="expr"></param>
        /// <param name="header"></param>
        /// <param name="sort"></param>
        /// <param name="style"></param>
        /// <returns></returns>
        public PageModel<T> ColumFor(Expression<Func<T, object>> expr, string header = "", bool sort = false, string style = "")
        {
            var exprBody = expr.Body.ToString();
            if (exprBody.Contains("Convert"))
            {
                exprBody = exprBody.Replace("Convert", "").Replace("(", "").Replace(")", "");
            }
            var field = exprBody.Split('.').Last();//ExpressionHelper.GetExpressionText(expr);
            if (string.IsNullOrEmpty(header))
            {
                try
                {
                    var metadata = ModelMetadata.FromLambdaExpression<T, object>(expr, new ViewDataDictionary<T>());
                    string resolvedDisplayName = metadata.DisplayName ?? metadata.PropertyName ?? field.Split('.').Last();
                    header = HttpUtility.HtmlEncode(resolvedDisplayName);
                }
                catch//处理比如datetime类型的属性
                {
                    try
                    {
                        //ModelMetadataProvider provider = ModelMetadataProviders.Current;
                        //ModelMetadata containerMetadata = new ModelMetadata(provider, null, () => null, typeof(T), null);
                        //var metadata = containerMetadata.Properties.FirstOrDefault(m => m.PropertyName == field);
                        var metadata = GetModelMetadata<T>(field);
                        string resolvedDisplayName = metadata.DisplayName ?? metadata.PropertyName ?? field.Split('.').Last();
                        header = HttpUtility.HtmlEncode(resolvedDisplayName);
                    }
                    catch { }
                }
            }
            this.Colums.Add(new PageColum<T>()
            {
                Field = field,
                Header = header,
                Style = style,
                Sort = sort
            });
            return this;
        }
        /// <summary>
        /// 列
        /// </summary>
        /// <param name="header"></param>
        /// <param name="func"></param>
        /// <param name="style"></param>
        /// <returns></returns>
        public PageModel<T> Colum(string header, Func<T, object> func, bool sort = false, string style = "")
        {
            this.Colums.Add(new PageColum<T>()
            {
                Field = "",
                Header = header,
                Style = style,
                Format = func,
                Sort = sort
            });
            return this;
        }
        public MvcHtmlString ToMvcHtmlString()
        {
            var Model = this;
            var html = new StringBuilder();
            if (Model.Order != null && Model.Order.Field != "")
            {
                html.Append(string.Format("<input name="[PageModel_Order]" type="hidden" value="{0}">", Model.Order.Field + "|" + Model.Order.Order.ToString()));
            }
            else
            {
                html.Append(string.Format("<input name="[PageModel_Order]" type="hidden" value="{0}">", ""));
            }
            html.Append(string.Format("<input name="[PageModel_PageIndex]" type="hidden" value="{0}">", 1));
            html.Append(string.Format("<input name="[PageModel_PageSize]" type="hidden" value="{0}">", Model.PageSize.ToString()));
            html.Append(string.Format("<input name="[PageModel_CheckSearch]" type="hidden" value="{0}">", "1"));
            html.Append(string.Format("<input name="[PageModel_SelectIds]" type="hidden" value="{0}">", ""));
            html.Append(string.Format("<input name="[PageModel_PageTotal]" type="hidden" value="{0}">", Model.PageTotal));


            #region 表

            var columCount = 0;

            html.Append(string.Format("<table class="{0}">",this.TableClassName));
            html.Append("<thead>");
            html.Append("<tr>");
            //html.Append("<th>[]</th>");//列头
            if (Colums != null)
            {
                columCount = Colums.Count;
                if (this.ShowCheckBox)
                {
                    columCount += 1;
                    html.Append("<th style=" 40px;" ><input class="baseui-checkbox" onchange="PageModelCheck('pageModelCheck_All')" id="pageModelCheck_All" name="pageModelCheck_All" type="checkbox" value="true">选择</th>");
                }
                foreach (var colum in Colums)
                {
                    if (colum.Sort)
                    {
                        html.Append(string.Format("<th ><a href="javascript:;" onclick="SearchPageModelOrder('{2}','{0}');">{1}</a></th>"
                            , colum.Field
                            , colum.Header
                            , this.SearchFormId));
                    }
                    else
                    {
                        html.Append(string.Format("<th ><a href="javascript:;">{0}</a></th>", colum.Header));
                    }
                }
            }
            html.Append("</tr>");
            html.Append("</thead>");
            html.Append("<tbody>");
            if (Model != null && Model.DataSource.Count() > 0)
            {
                //html.Append("<td>[]</td>");//列
                var rows = this.CreateRows();
                foreach (var item in rows)
                {
                    html.Append("<tr>");
                    if (this.ShowCheckBox)
                    {
                        html.Append(string.Format("<td><input class="baseui-checkbox" onchange="PageModelCheck('pageModelCheck_{0}')" id="pageModelCheck_{0}" name="pageModelCheck_{0}" type="checkbox" value="true"></td>", item.SourcePrimaryKey));
                    }

                    foreach (var colum in item.RowData)
                    {
                        html.Append(string.Format("<td>{0}</td>", colum.Vaule));
                    }
                    html.Append("</tr>");
                }

                html.Append("</tbody>");
                html.Append("<tfoot>");
                html.Append("<tr>");
                html.Append(string.Format("<td colspan="{0}">", columCount));
                html.Append("<div class="baseui-paging">");
                if (Model.PageIndex == 1)
                {
                    html.Append(" <a href="javascript:;" class="baseui-paging-prev">");
                    html.Append("<i class="iconfont" ></i> 第一页");
                    html.Append("</a>");
                }
                else
                {
                    html.Append(string.Format(" <a href="javascript:;" onclick="SearchPageModelPage('{0}','1');" class="baseui-paging-prev">", this.SearchFormId));
                    html.Append("<i class="iconfont" ></i> 第一页");
                    html.Append("</a>");
                }
                var pNumber = 10;
                var start = GetStartNumber(Model.PageIndex, Model.PageTotal, pNumber);
                for (int i = 0; i < pNumber; i++)
                {
                    if (start + i <= Model.PageTotal)
                    {
                        if (start + i == Model.PageIndex)
                        {
                            html.Append(string.Format("<a href="javascript:;" class="baseui-paging-item baseui-paging-current">{0}</a>", start + i));
                        }
                        else
                        {
                            html.Append(string.Format("<a href="javascript:;" onclick="SearchPageModelPage('{1}','{0}');" class="baseui-paging-item">{0}</a>", start + i, this.SearchFormId));
                        }
                    }
                }
                if (Model.PageIndex == Model.PageTotal || Model.PageTotal == 0)
                {
                    html.Append("<a href="javascript:;" class="baseui-paging-next">最后一页 <i class="iconfont" ></i></a>");
                }
                else
                {
                    html.Append(string.Format("<a href="javascript:;" onclick="SearchPageModelPage('{1}','{0}');" class="baseui-paging-next">最后一页 <i class="iconfont"></i></a>", Model.PageTotal, this.SearchFormId));
                }
                html.Append(string.Format("<span class="baseui-paging-info"><span class="baseui-paging-bold">{0}/{1}</span>页</span>", Model.PageIndex, Model.PageTotal));
                html.Append("<span class="baseui-paging-which">");
                html.Append(string.Format("<input name="[psome_name]" value="{0}" type="text">", Model.PageIndex));
                html.Append("</span>");
                html.Append(string.Format(" <a class="baseui-paging-info baseui-paging-goto" href="javascript:;" onclick="SearchPageModelPageJmp('{0}')">跳转</a>", this.SearchFormId));
                html.Append(" </div>");
                html.Append(" </td>");
                html.Append("</tr>");
                html.Append("</tfoot>");
                html.Append("</table>");
            }
            else
            {
                html.Append("<tr>");
                html.Append(string.Format("<td colspan="{0}">暂无数据</td>", columCount));
                html.Append("</tr>");
                html.Append("</tbody>");
                html.Append("</table>");

            }
            #endregion
            html.Append("<script>    function SearchPageModelOrder(searchFormId, value) {        var oldValue = $("input[name='[PageModel_Order]']").val();        var newValue = "";        if (oldValue == "" || oldValue == value + "|Desc")            $("input[name='[PageModel_Order]']").val(value + "|Asc");       else  $("input[name='[PageModel_Order]']").val(value + "|Desc"); $("input[name='[PageModel_CheckSearch]']").val("0");$("#" + searchFormId).submit();}function SearchPageModelPage(searchFormId, value) {$("input[name='[PageModel_PageIndex]']").val(value);$("input[name='[PageModel_CheckSearch]']").val("0");$("#" + searchFormId).submit();} function SearchPageModelPageJmp(searchFormId) {var pindex = $("input[name='[psome_name]']").val();$("input[name='[PageModel_PageIndex]']").val(pindex);$("#" + searchFormId).submit();}");

            string js = "function PageModelCheck(v) {var id = v.split('_')[1];  var oldValue=$("input[name='[PageModel_SelectIds]']").val();    if ($("#" + v).is(":checked")) {  if (id == "All") {                $("input:checkbox").each(function (i, ele) {                    var cid = $(ele).attr("id");                    if (cid.indexOf("pageModelCheck") >= 0) {                        $(ele).attr("checked", true);                    }                });                $("input[name='[PageModel_SelectIds]']").val(id);            }           else {                if (oldValue.indexOf(id) < 0) {                   var newValue = oldValue + "|" + id;                    $("input[name='[PageModel_SelectIds]']").val(newValue);                }            }       }        else {            if (id == "All") {                $("input:checkbox").each(function (i, ele) {                    var cid = $(ele).attr("id");                    if (cid.indexOf("pageModelCheck") >= 0) {                        $(ele).attr("checked", false);                    }                });                $("input[name='[PageModel_SelectIds]']").val("");            }           else {                if (oldValue.indexOf(id) >= 0) {                    var newValue = oldValue.replace("|"+id,"");                    $("input[name='[PageModel_SelectIds]']").val(newValue);                }            }        }    }";

            html.Append(js);

            html.Append("  function PageModeSelectIds() {        var ids = $("input[name='[PageModel_SelectIds]']").val();        return ids;}");

            html.Append(" </script>");
            return MvcHtmlString.Create(html.ToString());
        }
        private List<PageRow> CreateRows()
        {
            var rows = new List<PageRow>();
            //ModelMetadataProvider provider = ModelMetadataProviders.Current;
            //ModelMetadata containerMetadata = new ModelMetadata(provider, null, () => null, typeof(T), null);
            //var properties = containerMetadata.Properties.Select(m => m.PropertyName);
            if (this.DataSource != null && this.DataSource.Count() > 0 && this.Colums != null && this.Colums.Count > 0)
            {
                foreach (var data in this.DataSource)
                {
                    var row = new PageRow();
                    if (!string.IsNullOrEmpty(this.SourcePrimaryKey))
                    {
                        var keyValue = data.GetType().GetProperty(this.SourcePrimaryKey).GetValue(data, null);
                        row.SourcePrimaryKey = keyValue == null ? Guid.NewGuid().ToString() : keyValue.ToString();
                    }
                    else
                    {
                        row.SourcePrimaryKey = Guid.NewGuid().ToString();
                    }
                    foreach (var colum in this.Colums)
                    {
                        if (!string.IsNullOrEmpty(colum.Field))
                        {
                            var colValue = data.GetType().GetProperty(colum.Field).GetValue(data, null);
                            row.RowData.Add(new RowItem() { ColumId = colum.Id, Vaule = colValue, CheckFieldColum = true});

                        }
                        else
                        {
                            var html = Format(colum.Format, data);
                            row.RowData.Add(new RowItem() { ColumId = colum.Id, Vaule = HttpUtility.HtmlEncode(html), CheckFieldColum = false });

                        }
                    }
                    rows.Add(row);
                }
            }
            return rows;
        }
        /// <summary>
        /// 执行委托
        /// </summary>
        /// <param name="format">lambda表达示</param>
        /// <param name="arg">委托参数</param>
        /// <returns></returns>
        private HelperResult Format(Func<T, object> format, dynamic arg)
        {
            var result = format.Invoke(arg);
            return new HelperResult(tw =>
            {
                var helper = result as HelperResult;
                if (helper != null)
                {
                    helper.WriteTo(tw);
                    return;
                }
                IHtmlString htmlString = result as IHtmlString;
                if (htmlString != null)
                {
                    tw.Write(htmlString);
                    return;
                }
                if (result != null)
                {
                    tw.Write(HttpUtility.HtmlEncode(result));
                }
            });
        }
        /// <summary>
        /// 获得一个数左右多少个的起始数
        /// </summary>
        /// <param name="helper"></param>
        /// <param name="currentNumber">当前数</param>
        /// <param name="maxNumber">最大数</param>
        /// <param name="showCount">一共多少个</param>
        /// <returns></returns>
        private Int64 GetStartNumber(Int64 currentNumber, Int64 maxNumber, int showCount)
        {
            var arr = new List<Int64>();
            var pAvg = showCount / 2;//左右显示个数
            for (int i = 1; i <= pAvg; i++)
            {
                if (currentNumber - i > 0)
                {
                    arr.Add(currentNumber - i);
                }
                if (currentNumber + i <= maxNumber)
                {
                    arr.Add(currentNumber + i);
                }
            }
            arr.Add(currentNumber);
            if (arr.Count < 10)
            {
                var le = showCount - arr.Count;
                var min = arr.Min();
                var max = arr.Max();
                for (int i = 1; i <= le; i++)
                {
                    if (min == 1 && max + 1 <= maxNumber)
                    {
                        arr.Add(max + 1);
                    }
                    if (max == maxNumber && min - 1 >= 1)
                    {
                        arr.Add(min - 1);
                    }
                }
            }
            return arr.Min();
        }

        private ModelMetadata GetModelMetadata<T>(string PropertyName)
        {
            ModelMetadataProvider provider = ModelMetadataProviders.Current;
            ModelMetadata containerMetadata = new ModelMetadata(provider, null, () => null, typeof(T), null);
            var metadata = containerMetadata.Properties.FirstOrDefault(m => m.PropertyName == PropertyName);
            return metadata;
        }

        public string ToHtmlString()
        {
            return this.ToMvcHtmlString().ToHtmlString();
        }
    }
}

  

9.添加一个设置对Html的替换规则类:MvcHtmlWrapper.cs

using System;
using System.Collections.Generic;
using System.Diagnostics.Contracts;
using System.Linq;
using System.Text;
using System.Web;
using System.Web.Mvc;

namespace System.Web.Mvc
{
    /// <summary>
    /// MvcHtmlString包装器
    /// 用于设置对Html的替换规则并在输出时统一处理显示Html
    /// </summary>
    public class MvcHtmlWrapper : IHtmlString
    {
        /// <summary>
        /// 构建一个MvcHtmlWrapper,如果是MvcHtmlWrapper则直接返回,
        /// 如果是是其它类型则构造MvcHtmlWrapper后返回
        /// </summary>
        /// <param name="str">IHtmlString类型,实现了ToHtmlString接口的类型</param>
        /// <returns></returns>
        public static MvcHtmlWrapper Create(IHtmlString str)
        {
            Contract.Requires(str != null);
            if (str is MvcHtmlWrapper)
                return str as MvcHtmlWrapper;
            if (str is MvcHtmlString)
                return new MvcHtmlWrapper(str);
            Contract.Assert(false);
            return null;
        }

        IHtmlString HtmlStringInterface { get; set; }

        private string _htmlString;

        /// <summary>
        /// 获取MvcHtmlString所生成的Html字符串
        /// </summary>
        public string HtmlString
        {
            get { return _htmlString ?? (_htmlString = HtmlStringInterface.ToHtmlString()); }
        }

        /// <summary>
        /// 用于替换的Dict
        /// </summary>
        public List<Tuple<string, string>> ReplaceDict { get; set; }

        /// <summary>
        /// 构造MvcHtmlString包装器
        /// </summary>
        /// <param name="str">MvcHtmlString的实例,不允许为空</param>
        MvcHtmlWrapper(IHtmlString str)
        {
            Contract.Requires(str != null);
            HtmlStringInterface = str;
            ReplaceDict = new List<Tuple<string, string>>();
        }

        /// <summary>
        /// 对ToHtmlString进行了重写, 输出HtmlString的内容,并按替换规则进行了替换
        /// </summary>
        /// <returns></returns>
        public string ToHtmlString()
        {
            return ToString();
        }

        /// <summary>
        /// 对ToString进行了重写, 输出HtmlString的内容,并按替换规则进行了替换
        /// </summary>
        /// <returns></returns>
        public override string ToString()
        {
            var sb = new StringBuilder(HtmlString);
            foreach (var item in ReplaceDict)
            {
                if (!string.IsNullOrEmpty(item.Item1))
                {
                    sb.Replace(item.Item1, item.Item2);
                }
            }
            return sb.ToString();
        }

        /// <summary>
        /// 添加替换原则
        /// </summary>
        /// <param name="item1">被替换的字符串</param>
        /// <param name="item2">替换为的字符串</param>
        internal void Add(string item1, string item2)
        {
            ReplaceDict.Add(Tuple.Create(item1, item2));
        }
    }
}
View Code

10.添加一个MVC Html的扩展类:MvcHtmlStringExtension.cs

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics.Contracts;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Web;
using System.Web.Mvc;

namespace System.Web.Mvc
{
    [EditorBrowsable(EditorBrowsableState.Never)]
    public static class MvcHtmlStringExtension
    {
        /// <summary>
        /// 扩展分页查询表
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="helper"></param>
        /// <param name="SearchFormId">要查询的form表单ID</param>
        /// <returns></returns>
        public static PageModel<T> PageTableFor<T>(this HtmlHelper<PageModel<T>> helper, string SearchFormId) where T : class
        {
            var model = helper.ViewData.Model;
            model = model.SetSearchFormId(SearchFormId);
            return model;
        }
        #region ForSearch

        /// <summary>
        /// 为当前表单元素添加搜索条件
        /// </summary>
        /// <param name="str"></param>
        /// <param name="method">搜索方法</param>
        /// <param name="prefix">前缀</param>
        /// <param name="hasId">是否显示Id,默认false</param>
        /// <param name="orGroup">如果想要支援Or,请设置一个Or分组</param>
        /// <returns></returns>
        public static MvcHtmlWrapper ForSearch(this IHtmlString str, QueryMethod? method, string prefix = "", bool hasId = false, string orGroup = "")
        {
            var wrapper = MvcHtmlWrapper.Create(str);
            Contract.Assert(null != wrapper);
            if (!method.HasValue) return wrapper;
            var html = wrapper.HtmlString;
            #region 如果是CheckBox,则去掉hidden

            if (html.Contains("type="checkbox""))
            {
                var checkMatch = Regex.Match(html, "<input name="[^"]+" type="hidden" [^>]+ />");
                if (checkMatch.Success)
                {
                    wrapper.Add(checkMatch.Groups[0].Value, string.Empty);
                }
            }

            #endregion

            #region 替换掉Name
            var match = Regex.Match(html, "name="(?<name>[^"]+)"");
            var strInsert = "";
            if (!string.IsNullOrWhiteSpace(prefix))
            {
                strInsert += string.Format("({0})", prefix);
            }
            if (!string.IsNullOrWhiteSpace(orGroup))
            {
                strInsert += string.Format("{{{0}}}", orGroup);
            }
            if (match.Success)
            {
                wrapper.Add(match.Groups[0].Value,
                            string.Format("name="[{1}]{2}{0}"", match.Groups[1].Value, method, strInsert));
            }

            #endregion

            return wrapper;
        }

        #endregion
    }
}
View Code

11.添加一个模型映射类:SearchModelBinder.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Web.Mvc;

namespace System.Web.Mvc
{
    /// <summary>
    /// 对SearchModel做为Action参数的绑定
    /// </summary>
    public class SearchModelBinder : IModelBinder
    {
        public object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
        {
            var model = (PageModel)(bindingContext.Model ?? new PageModel());
            var dict = controllerContext.HttpContext.Request.Params;
            var keys = dict.AllKeys.Where(c => c.StartsWith("["));//我们认为只有[开头的为需要处理的
            if (keys.Count() != 0)
            {
                foreach (var key in keys)
                {
                    if (!key.StartsWith("[")) continue;
                    var val = dict[key];
                    //处理无值的情况
                    if (string.IsNullOrEmpty(val)) continue;
                    if (key == "[PageModel_Order]")//排序
                    {
                        var arr = val.Split('|');
                        if (arr.Length == 2)
                        {
                            model.Order = new QueryOrder() { Field = arr[0], Order = (OrderType)Enum.Parse(typeof(OrderType), arr[1]) };
                        }
                        continue;
                    }
                    if (key == "[PageModel_PageIndex]")//页码
                    {
                        try
                        {
                            var pindex = int.Parse(val);
                            if (pindex > 1)
                                model.PageIndex = pindex;
                            else
                                model.PageIndex = 1;
                            if (keys.Contains("[PageModel_PageTotal]"))
                            {
                                var pt = int.Parse(dict["[PageModel_PageTotal]"]);
                                if (pindex > pt)
                                {
                                    model.PageIndex = 1;
                                }
                            }
                        }
                        catch
                        {
                            model.PageIndex = 1;
                        }
                        continue;
                    }
                    if (key == "[PageModel_PageTotal]")
                    {
                        continue;
                    }
                    if (key == "[PageModel_PageSize]")//每页显示数量
                    {
                        try
                        {
                            var pSize = int.Parse(val);
                            if (pSize > 0)
                                model.PageSize = pSize;
                            else
                                model.PageSize = 20;
                        }
                        catch
                        {
                            model.PageSize = 20;
                        }
                        continue;
                    }
                    if (key == "[PageModel_CheckSearch]")
                    {
                        if (val == "1")
                        {
                            //model.che = 1;
                        }
                        continue;
                    }
                    if (key == "[PageModel_SelectIds]")
                    {
                        if (val == "All")
                        {
                            model.SelectAll = true;
                        }
                        else
                        {
                            model.SelectAll = false;
                            model.SelectPrimaryKeys = val.Split('|').Where(m => m != "").ToList();
                        }
                        continue;
                    }
                    if (key == "[psome_name]")
                    {
                        continue;
                    }
                    AddSearchItem(model, key, val);
                }
            }
            return model;
        }

        /// <summary>
        /// 将一组key=value添加入PageModel.SearchQuery
        /// </summary>
        /// <param name="model">PageModel</param>
        /// <param name="key">当前项的HtmlName</param>
        /// <param name="val">当前项的值</param>
        public static void AddSearchItem(PageModel model, string key, string val)
        {
            string field = "", prefix = "", orGroup = "", method = "";
            var keywords = key.Split(']', ')', '}');
            //将Html中的name分割为我们想要的几个部分
            foreach (var keyword in keywords)
            {
                if (Char.IsLetterOrDigit(keyword[0])) field = keyword;
                var last = keyword.Substring(1);
                if (keyword[0] == '(') prefix = last;
                if (keyword[0] == '[') method = last;
                if (keyword[0] == '{') orGroup = last;
            }
            if (string.IsNullOrEmpty(method)) return;
            if (!string.IsNullOrEmpty(field))
            {
                var item = new ConditionItem
                {
                    Field = field,
                    Value = val.Trim(),
                    Prefix = prefix,
                    OrGroup = orGroup,
                    Method = (QueryMethod)Enum.Parse(typeof(QueryMethod), method)
                };
                model.SearchQuery.Add(item);
            }
        }
    }
}
View Code

到此类库封闭完毕。我们将WEB引用此类库。
12.在Global.asax中添加:

ModelBinders.Binders.Add(typeof(PageModel), new SearchModelBinder());

13.现在我们WEB的Models中添加一个UserModel.cs进行实例展示:

using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Web;

namespace MvcApplication.Models
{
    public class UserModel
    {
        [Display(Name = "编号")]
        public virtual string Id { get; set; }
        [Display(Name = "姓名")]
        public virtual string Name { get; set; }
        /// <summary>
        /// true:男 false:女
        /// </summary>
        [Display(Name = "性别")]
        public virtual bool IsSex { get; set; }
        [Display(Name = "生日")]
        public virtual DateTime Birthday { get; set; }
        [Display(Name="性别")]
        public string SexName
        {
            get
            {
                return this.IsSex ? "" : "";
            }
        }
    }
}
View Code

14.修改HomeController:

using MvcApplication.Models;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;

namespace MvcApplication.Controllers
{
    public class HomeController : Controller
    {
        public ActionResult Index()
        {
            return View();
        }
        public ActionResult Table(PageModel model)
        {
            var data = CreateData();
            var dCount = data.Count;
            data = data.Skip((model.PageIndex - 1) * model.PageSize).Take(model.PageSize).ToList();
            return PartialView(model.Record<UserModel>(data, dCount));
        }


        private IList<UserModel> CreateData()
        {
            var list = new List<UserModel>();
            for (int i = 0; i < 100; i++)
            {
                list.Add(new UserModel() { 
                    Id=i.ToString(),
                    Name="姓名"+i.ToString(),
                    IsSex=true,
                    Birthday=DateTime.Now
                });
            }
            return list;
        }






        public ActionResult About()
        {
            ViewBag.Message = "你的应用程序说明页。";

            return View();
        }

        public ActionResult Contact()
        {
            ViewBag.Message = "你的联系方式页。";

            return View();
        }
    }
}
View Code

15.修改Index.cshtml:

@{
    ViewBag.Title = "主页";
}
@section featured {
  
}
<div id="tb001">
    @Html.Action("Table")
</div>
View Code

16.添加Table视图:

@model PageModel<MvcApplication.Models.UserModel>
@{
    Layout = null;
    var ajaxOption = new AjaxOptions()
   {
       HttpMethod = "Post",
       UpdateTargetId = "tb001",
       OnBegin = "$('#pageMode_tableConetnt').mask();",
       OnComplete = "$('#pageMode_tableConetnt').unmask();",
       InsertionMode = InsertionMode.Replace
   };
}
@using (Ajax.BeginForm("Table", "Home", null, ajaxOption, new { @id = "PageModel_Form" }))
{
    <div>
        <div class="baseui-box">
            <div class="baseui-box-head">
                <h3 class="baseui-box-head-title">查询</h3>
                <span class="baseui-box-head-text">Search</span>
            </div>
            <div class="baseui-box-container">
                <div class="baseui-box-content">
                    姓名:
                    @Html.TextBox(Model.SearchName(m => m.Name), Model.SearchValue(m => m.Name),
                    new { @class = "baseui-input" }).ForSearch(QueryMethod.Like)
                    <input type="submit" value="查询" class="baseui-button baseui-button-sorange" />
                </div>
            </div>
        </div>

        <br />
        <div class="baseui-box">
            <div class="baseui-box-head">
                <a href="@Url.Action("Add")" data-dialog-title="添加产品类型" data-dialog="true">
                    <i class="iconfont">&#xF023;</i>
                    添加
                </a>
            </div>
            <div class="baseui-box-container">
                <div class="baseui-box-content" style="padding: 0px !important;">
                    <div id="pageMode_tableConetnt">
                        @(Html.PageTableFor("PageModel_Form")
                            .SetClass("baseui-table")
                            .SetShowCheckBox(false)
                            .SetSourceKey(m => m.Id)
                            .ColumFor(m => m.Name)
                            .ColumFor(m=>m.SexName)
                            .Colum("生日",m=>m.Birthday.ToShortDateString())
                            .Colum("操作",
                                            @<text>

                                                    @Html.ActionLink("修改", "Edit", new { id = @item.Id }
                                                                    ,new 
                                                                    { 
                                                                        data_dialog = "true", 
                                                                        data_dialog_title = "修改产品类型" 
                                                                    })
                                                    |  
                                                    @Ajax.ActionLink("删除", "Delete", new { id = @item.Id }, ajaxOption
                                                                     , new
                                                                     {
                                                                         confirm_show = "true",
                                                                         confirm_tile = "提示",
                                                                         confirm_content = "是否删除?",
                                                                         confirm_height = 210
                                                                      })


                                            </text>)
                        )
                    </div>
                </div>
            </div>
        </div>

    </div> 
}
View Code

现在,我们看看运行效果:

当我们在姓名查询框中输入:张三
现在添加断点:


这样处理后,自己再进行处理封装是不是很方便呢。

有些功能尚未实现,请自行修改
本实例到此结束,如有不懂的地方请留言,如果大家觉得好请支持留言,如果有更好的处理方法请留言告知,不胜感激,在此谢谢了!!!

需要源码地址http://download.csdn.net/detail/cyb331/6806325

原文地址:https://www.cnblogs.com/cyb331/p/3504426.html