开发环境vs2010
css:bootstrap
js:jquery
bootstrap paginator
原先只是想做个mvc的分页,但是一般的数据展现都需要检索条件,而且是多个条件,所以就变成了MVC多条件+分页查询
因为美工不是很好,所以用的是bootstrap前端框架,自己懒得写前端的分页控件,用的是bootstrap paginator分页控件。
方式:
用Get方式提交检索条件,分页可用2种模式,无刷新或者带刷新的跳转。
Shared\_Layout.cshtml中添加css、js脚本引用:
1 <!DOCTYPE html> 2 <html> 3 <head> 4 <title>@ViewBag.Title</title> 5 <link href="@Url.Content("~/Content/bootstrap/css/bootstrap.min.css")" rel="stylesheet" media="screen" /> 6 <script type="text/javascript" src="@Url.Content("~/Scripts/jquery-1.7.1.min.js")" type="text/javascript"></script> 7 <script type="text/javascript" src="@Url.Content("~/Scripts/bootstrap.min.js")"></script> 8 </head> 9 10 <body> 11 <div class="container"> 12 @RenderBody() 13 </div> 14 </body> 15 </html>
查询页面(View)Index.cshtml:
引用分页插件库、生成分页脚本,定义分页跟数据展现的分部视图:
@Url.IncludePagerScript()
@Html.Pager("#pager", "#Content", "/Search/?page=", Model)
<div class="container"> <div id="pager"></div> <div id="Content"> @Html.Partial("IndexTable") </div> </div>
封装了下分页脚本:
@Html.Pager(分页控件, 数据展现, 分页的查询地址, 继承PagerSearchBase的Model,是否刷新默认为刷新的)
若要切换成分页的无刷新模式,只需要写成@Html.Pager("#pager", "#Content", "/Search/?page=", Model, false)
1 public static MvcHtmlString Pager(this HtmlHelper htmlHelper, string filter, string content, string url, MvcPagerSearch.Models.PagerSearchBase pagerbase, bool refresh = true) 2 { 3 return Pager(htmlHelper, filter, content, url, pagerbase.CurrentPage, pagerbase.PageCount, pagerbase.Condition, refresh); 4 } 5 6 public static MvcHtmlString Pager(this HtmlHelper htmlHelper, string filter, string content, string url, int currentPage, int pageCount, string condition = "", bool refresh = true) 7 { 8 if(pageCount <= 1) return new MvcHtmlString(string.Empty); 9 string requestUrl = string.Empty; 10 if(condition == null) condition = string.Empty; 11 if(condition.Length > 0 && condition.Substring(0, 1) != "&") 12 { 13 condition = "&" + condition; 14 } 15 requestUrl = """ + url + "" + page + "" + condition + "&rand=" + Math.random()"; 16 return new MvcHtmlString("<script type="text/javascript">$(function () {" 17 + " $("" + filter + "").bootstrapPaginator({ currentPage: " + currentPage + "," 18 + " totalPages: " + pageCount + "," 19 + " numberOfPages: 10," 20 + " size:"large"," 21 + " alignment: "center"," 22 + " useBootstrapTooltip: true," 23 + " tooltipTitles: function (type, page, current) {" 24 + " switch (type) {" 25 + " case "first":" 26 + " return "首页 <i class='icon-fast-backward icon-white'></i>";" 27 + " case "prev":" 28 + " return "上一页 <i class='icon-backward icon-white'></i>";" 29 + " case "next":" 30 + " return "下一页 <i class='icon-forward icon-white'></i>";" 31 + " case "last":" 32 + " return "最末页 <i class='icon-fast-forward icon-white'></i>";" 33 + " case "page":" 34 + " return "第 " + page + "页 <i class='icon-file icon-white'></i>";" 35 + " }" 36 + " }," 37 + " onPageClicked: function (event, originalEvent, type, page) {" 38 + (refresh ? " location.href = " + requestUrl + ";" : " $.post(" + requestUrl + ", function (data) { $("" + content + "").html(data); });") 39 + " }" 40 + " });" 41 + " });</script>"); 42 }
定义查询表单:
@using(Html.BeginForm("Index", "Search", FormMethod.Get, new { @class = "form-search form-inline" })) { <div class="input-append"> @Html.TextBoxFor(model => model.UserName, new { @class = "span2 search-query" }) <button type="submit" class="btn"> 快速查询</button> </div> }
整个Index.cshtml与分部视图IndexTable.cshtml的源代码:
1 @model MvcPagerSearch.Models.SearchModel 2 3 @{ 4 ViewBag.Title = "Index"; 5 } 6 @Url.IncludePagerScript() 7 @Html.Pager("#pager", "#Content", "/Search/?page=", Model) 8 9 <h2>查询</h2> 10 @using(Html.BeginForm("Index", "Search", FormMethod.Get, new { @class = "form-search form-inline" })) 11 { 12 <div class="input-append"> 13 @Html.TextBoxFor(model => model.UserName, new { @class = "span2 search-query" }) 14 <button type="submit" class="btn"> 15 快速查询</button> 16 </div> 17 } 18 19 <div class="container"> 20 <div id="pager"></div> 21 <div id="Content"> 22 @Html.Partial("IndexTable") 23 </div> 24 </div>
1 @model MvcPagerSearch.Models.SearchModel 2 <table class="table table-hover"> 3 <thead> 4 <tr> 5 <th> 6 昵称 7 </th> 8 <th> 9 性别 10 </th> 11 <th> 12 年龄 13 </th> 14 </tr> 15 </thead> 16 <tbody> 17 @foreach(var entity in Model.Members) 18 { 19 <tr> 20 <td> 21 @entity.UserName 22 </td> 23 <td> 24 @entity.Sex 25 </td> 26 <td> 27 @entity.Age 28 </td> 29 </tr> 30 } 31 </tbody> 32 </table>
控制器(Control)SearchController.cs:
Index:
1 public ActionResult Index(int page = 1) 2 { 3 SearchModel conditionData = SearchModel.Create(Request, GetMembers()); 4 conditionData.Search(page); 5 6 if(Request.IsAjaxRequest()) return PartialView("IndexTable", conditionData); 7 return View("Index", conditionData); 8 }
取得数据(测试数据):
1 // 获取数据 2 private List<Member> GetMembers() 3 { 4 List<Member> result = new List<Member>(); 5 for(int i = 0; i <= 100; i++) 6 { 7 result.Add(new Member() { UserName = "A" + i, Age = i, Sex = i % 2 == 0 ? "男" : "女" }); 8 } 9 return result; 10 }
模型(Model)SearchModel.cs、Member.cs:
SearchModel继承自PagerSearchBase
1 public class SearchModel : PagerSearchBase 2 { 3 public string UserName { get; set; } 4 5 public IEnumerable<Member> Members { get; set; } 6 }
创建SearchModel对象的方法:
1 public static SearchModel Create(HttpRequestBase request, IEnumerable<Member> members) 2 { 3 SearchModel result = new SearchModel(); 4 result.AddFields(request, "UserName");
5 result.Members = members; 6 return result; 7 }
protected void AddFields(HttpRequestBase request, params string[] fieldNames);
用于添加查询条件的属性名,并为属性设置值,这里的属性只能是string类型的
重载子类的SearchByPage函数
1 protected override void SearchByPage(int page) 2 { 3 // 过滤 4 Members = Members.Where(UserName, entity => entity.UserName.Contains(UserName)); 5 // 分页 6 Members = Pager(Members.OrderBy(entity => entity.UserName)); 7 }
扩展了下IEnumerable<TSource>的Where函数,若遇到UserName为空,则不进行条件过滤,且能链式调用
1 public static IEnumerable<TSource> Where<TSource>(this IEnumerable<TSource> data, string condition, Func<TSource, bool> predicate) 2 { 3 if(string.IsNullOrEmpty(condition)) return data; 4 return data.Where(predicate); 5 } 6 7 public static IEnumerable<TSource> Where<TSource>(this IEnumerable<TSource> data, string condition, Func<TSource, int, bool> predicate) 8 { 9 if(string.IsNullOrEmpty(condition)) return data; 10 return data.Where(predicate); 11 }
PagerSearchBase.cs基类
1 public abstract class PagerSearchBase 2 { 3 /// <summary> 4 /// 每页行数,默认20,子类可调 5 /// </summary> 6 protected int pageSize = 20; 7 private int pageCount = 0; 8 private Hashtable hsCondition = new Hashtable(); 9 10 /// <summary> 11 /// 总页数 12 /// </summary> 13 public int PageCount { get { return pageCount; } set { pageCount = value; } } 14 15 /// <summary> 16 /// 当前页 17 /// </summary> 18 public int CurrentPage { get; protected set; } 19 20 /// <summary> 21 /// 条件Url 22 /// </summary> 23 public string Condition { get; protected set; } 24 25 /// <summary> 26 /// 按页查询 27 /// </summary> 28 /// <param name="page"></param> 29 protected abstract void SearchByPage(int page); 30 31 /// <summary> 32 /// 取得条件,可外部调用 33 /// </summary> 34 /// <returns></returns> 35 public string GetCondition() 36 { 37 string result = string.Empty; 38 int i = 0; 39 foreach(object key in hsCondition.Keys) 40 { 41 if(i++ > 0) 42 result += "&"; 43 result += key.ToString() + "=" + HttpUtility.UrlEncode(hsCondition[key].ToString().Trim()); 44 } 45 return result; 46 } 47 48 /// <summary> 49 /// 按页查询,外部调用 50 /// </summary> 51 /// <param name="page"></param> 52 public void Search(int page) 53 { 54 // 设置当前页 55 CurrentPage = page; 56 // 取得反馈的条件Url 57 Condition = GetCondition(); 58 SearchByPage(page); 59 } 60 61 /// <summary> 62 /// 批量添加用于查询条件的属性名,并为属性设置值 63 /// </summary> 64 /// <param name="request"></param> 65 /// <param name="fieldNames"></param> 66 protected void AddFields(HttpRequestBase request, params string[] fieldNames) 67 { 68 for(int i = 0; i <= fieldNames.Length - 1; i++) 69 { 70 string fieldName = fieldNames[i]; 71 string value = WebUtil.GetSafeQueryString(request, fieldName).Trim(); 72 // 设置属性值 73 this.GetType().GetProperty(fieldName).SetValue(this, value, null); 74 // 添加反馈的条件Url 75 AddCondition(fieldName, value); 76 } 77 } 78 79 /// <summary> 80 /// 分页 81 /// </summary> 82 /// <typeparam name="T"></typeparam> 83 /// <param name="searchData"></param> 84 /// <returns></returns> 85 protected IEnumerable<T> Pager<T>(IEnumerable<T> searchData) 86 { 87 return PagerUtil.GetPageData(CurrentPage, pageSize, searchData, out pageCount); 88 } 89 90 /// <summary> 91 /// 添加反馈的条件Url,内部方法 92 /// </summary> 93 /// <param name="name"></param> 94 /// <param name="value"></param> 95 private void AddCondition(string name, string value) 96 { 97 if(!string.IsNullOrEmpty(value)) 98 hsCondition.Add(name, value); 99 } 100 }
Member.cs
1 public class Member 2 { 3 public string UserName { get; set; } 4 public int Age { get; set; } 5 public string Sex { get; set; } 6 }
这样就完成了多条件查询+分页的页面。
如果要增加条件,就只要修改Model跟View就可以了
如要增加个Age的条件:
修改Model:
增加属性字段:public string Age { get; set; }
原result.AddFields(request, "UserName");改为result.AddFields(request, "UserName", "Age");
SearchByPage中增加过滤条件:
1 protected override void SearchByPage(int page) 2 { 3 int age = 0; 4 if(!Int32.TryParse(Age, out age)) Age = string.Empty; 5 // 过滤 6 Members = Members.Where(UserName, entity => entity.UserName.Contains(UserName)) 7 .Where(Age, entity => entity.Age == age); 8 // 分页 9 Members = Pager(Members.OrderBy(entity => entity.UserName)); 10 }
完整的SearchModel.cs文件:
1 public class SearchModel : PagerSearchBase 2 { 3 public string UserName { get; set; } 4 public string Age { get; set; } 5 6 public IEnumerable<Member> Members { get; set; } 7 8 public static SearchModel Create(HttpRequestBase request, IEnumerable<Member> members) 9 { 10 SearchModel result = new SearchModel(); 11 result.AddFields(request, "UserName", "Age"); 12 result.Members = members; 13 return result; 14 } 15 16 protected override void SearchByPage(int page) 17 { 18 int age = 0; 19 if(!Int32.TryParse(Age, out age)) Age = string.Empty; 20 // 过滤 21 Members = Members.Where(UserName, entity => entity.UserName.Contains(UserName)) 22 .Where(Age, entity => entity.Age == age); 23 // 分页 24 Members = Pager(Members.OrderBy(entity => entity.UserName)); 25 } 26 }
修改View:
在Index.cshtml查询的表单中增加查询条件:
@Html.TextBoxFor(model => model.Age, new { @class = "span2 search-query" })
完整的Index.cshtml文件:
1 @model MvcPagerSearch.Models.SearchModel 2 3 @{ 4 ViewBag.Title = "Index"; 5 } 6 @Url.IncludePagerScript() 7 @Html.Pager("#pager", "#Content", "/Search/?page=", Model) 8 9 <h2>查询</h2> 10 @using(Html.BeginForm("Index", "Search", FormMethod.Get, new { @class = "form-search form-inline" })) 11 { 12 <div class="input-append"> 13 @Html.TextBoxFor(model => model.Age, new { @class = "span2 search-query" }) 14 @Html.TextBoxFor(model => model.UserName, new { @class = "span2 search-query" }) 15 <button type="submit" class="btn"> 16 快速查询</button> 17 </div> 18 } 19 20 <div class="container"> 21 <div id="pager"></div> 22 <div id="Content"> 23 @Html.Partial("IndexTable") 24 </div> 25 </div>
就可以了,应该是挺方便了
完整项目文件下载: