注:文字写作是本人弱项,如描述有问题,请见谅!!!
前言:在开发中,经常使用查询分页,为了达到统一与复用,进行的统合实例,本实例将一步一步实现一个统合的查询分页的实现。
开发工具: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 } }
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 } }
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; } } }
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; } } }
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; } } }
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=\"width: 40px;\" ><input class=\"baseui-checkbox\" οnchange=\"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:;\" οnclick=\"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\" οnchange=\"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:;\" οnclick=\"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:;\" οnclick=\"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:;\" οnclick=\"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:;\" οnclick=\"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)); } } }
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 } }
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); } } } }
到此类库封闭完毕。我们将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 ? "男" : "女"; } } } }
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(); } } }
15.修改Index.cshtml:
@{ ViewBag.Title = "主页"; } @section featured { } <div id="tb001"> @Html.Action("Table") </div>
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"></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> }
现在,我们看看运行效果:
当我们在姓名查询框中输入:张三
现在添加断点:
这样处理后,自己再进行处理封装是不是很方便呢。
有些功能尚未实现,请自行修改
本实例到此结束,如有不懂的地方请留言,如果大家觉得好请支持留言,如果有更好的处理方法请留言告知,不胜感激,在此谢谢了!!!