asp.net mvc多条件+分页查询解决方案

开发环境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>
_Layout.cshtml

查询页面(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         }
Html.Pager的源代码

定义查询表单:

@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>
Index.cshtml
 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>
IndexTable.cshtml


控制器(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         }
扩展Where函数

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     }
PagerSearchBase.cs

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     }
SearchModel.cs

修改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>
Index.cshtml

就可以了,应该是挺方便了

完整项目文件下载:

http://files.cnblogs.com/nickppa/MvcPagerSearch.rar

原文地址:https://www.cnblogs.com/nickppa/p/3232535.html