上篇过后,被评为没有什么技术含量了,但我觉得这并没有什么问题,因为文章不一定会让所有人群受益,文章或适于新手,或适于熟手。但凡是对人有所启发,我觉得写文章有值得。
  而且我觉得这一系列主要是在开发中遇到的问题及解决方法,有容易想到的,有经过几次开发迭代才形成的。还是那句话,这些未必是一些高效的技巧,但是的确是能解决问题,也未必有什么高深的原理,只是我觉得值得分享。
  3.Pager
  3.1需求及模拟代码
  需求,假设我们有个列表,有分页功能,我们可能需要一个页码列表,如
  ![image image]() 
 
  我们模拟写一下Action:
             1: public ActionResult Index(int? p)
          2: {          3:     if (!p.HasValue) p = 1;//如果未对p传值就是第1页
          4:     var list = new List<int>();//生成一个模拟列表
          5:     for (var i = 0; i < 10;i++ )
          6:     {          7:         list.Add(p.Value);//是第几页就向中填充几个这个页码的数
          8:     }
          9:     return View(list);//强型传递给View
         10: }
      View中我写以下显示方式:
             1: <%@ Page Language="C#" MasterPageFile="~/Views/Shared/Site.Master" Inherits="System.Web.Mvc.ViewPage<List<int>>" %>
          2:  
          3: <asp:Content ID="indexTitle" ContentPlaceHolderID="TitleContent" runat="server">
          4:     Pager for List
          5: </asp:Content>
          6:  
          7: <asp:Content ID="indexContent" ContentPlaceHolderID="MainContent" runat="server">
          8:     <div>
          9:         <ul>
         10:             <%foreach (int i in Model){//显示这个列表%>         11:             <li><%=i %></li>
         12:             <%} %>
         13:         </ul>
         14:     </div>
         15:     <!--将在这里显示分页的部分-->
         16:    </asp:Content>
          下面是运行后的结果:
  第一页URL类似/Home/Index?p=1
  ![image image]() 
 
  第二页URL类似/Home/Index?p=2
  ![image image]() 
 
  其它页面以此类推
    3.2最简单的解决方案
  我想最简单无非就是直接写链接,当然也要考虑更换Routing规则的问题,所以我们可以最简单如下来写:
             1: <%
          2:           int p = 1;
          3:           int.TryParse(Request.QueryString["p"], out p);
          4: %>
          5: <div>
          6: <%=Html.ActionLink("上一页", "Index", new { p= p-1})%>          7: <strong>当前页:<%=p %></strong>
          8: <%=Html.ActionLink("下一页", "Index", new { p= p+1})%>          9: </div>
      这样就可以得到如果下的分页样式
  ![image image]() 
 
  当然,也可以根据这个来写1,2,3,4,5页的链接,而不写“上一页”或“下一页”
  但是这种方法有个问题,就是使用Html.ActionLink的时候要用字符串来指定Action和Controller。下面我们来改换另一种方法来实现
  3.3使用RouteLink来实现
  我们使用Html.RouteLink就可以实现不与Action或Controller的名称相耦合,例如:
             1: <%for (int i = 1; i < 10; i++)
          2:     {          3:         ViewContext.RouteData.Values["p"] = i;//设置页码
          4:         Writer.Write(
          5:             Html.RouteLink(i.ToString(), ViewContext.RouteData.Values)
          6:             );//显示设置页面后的链接
          7:         Writer.Write(" ");//连接后显示个空格,好看点          8:       
          9:     }%>
      这个列表,我们就可以显示为
  ![image image]() 
 
  3.4完善这个Pager并封装成一个Helper
  上面列出了Pager,但是有几个问题
  - 没有上下页
- 没有指定当前页的特殊显示
- 每次调用时都要写一次
- 如果QueryString有其它参数时无法处理
那我们下面来完善这个Pager
  并将之封装成一个Helper
  1![]() using System;
using System;
  2![]() using System.Collections.Generic;
using System.Collections.Generic;
  3![]() using System.Linq;
using System.Linq;
  4![]() using System.Web;
using System.Web;
  5![]() using System.Web.Mvc;
using System.Web.Mvc;
  6![]() using System.Web.Routing;
using System.Web.Routing;
  7![]() using System.Text;
using System.Text;
  8![]() using System.Web.Mvc.Html;
using System.Web.Mvc.Html;
  9![]()
 10![]() namespace MvcApplication2.Helpers
namespace MvcApplication2.Helpers
 11![]()
![]()
![]() {
{
 12![]() public static class PagerExtensions
    public static class PagerExtensions
 13![]()
![]() 
    ![]() {
{
 14![]()
![]() /**//// <summary>
        /**//// <summary>  
 15![]() /// 分页Pager显示
        /// 分页Pager显示  
 16![]() /// </summary>
        /// </summary>   
 17![]() /// <param name="html"></param>
        /// <param name="html"></param>  
 18![]() /// <param name="currentPageStr">标识当前页码的QueryStringKey</param>
        /// <param name="currentPageStr">标识当前页码的QueryStringKey</param>   
 19![]() /// <param name="pageSize">每页显示</param>
        /// <param name="pageSize">每页显示</param>  
 20![]() /// <param name="totalCount">总数据量</param>
        /// <param name="totalCount">总数据量</param>  
 21![]() /// <returns></returns>
        /// <returns></returns> 
 22![]() public static string Pager(this HtmlHelper html, string currentPageStr, int pageSize, int totalCount)
        public static string Pager(this HtmlHelper html, string currentPageStr, int pageSize, int totalCount)
 23![]()
![]() 
        ![]() {
{
 24![]() var queryString = html.ViewContext.HttpContext.Request.QueryString;
            var queryString = html.ViewContext.HttpContext.Request.QueryString;
 25![]() int currentPage = 1; //当前页
            int currentPage = 1; //当前页  
 26![]() var totalPages = Math.Max((totalCount + pageSize - 1) / pageSize, 1); //总页数
            var totalPages = Math.Max((totalCount + pageSize - 1) / pageSize, 1); //总页数  
 27![]() var dict = new System.Web.Routing.RouteValueDictionary(html.ViewContext.RouteData.Values);
            var dict = new System.Web.Routing.RouteValueDictionary(html.ViewContext.RouteData.Values);
 28![]() var output = new System.Text.StringBuilder();
            var output = new System.Text.StringBuilder();
 29![]() if (!string.IsNullOrEmpty(queryString[currentPageStr]))
            if (!string.IsNullOrEmpty(queryString[currentPageStr]))
 30![]()
![]() 
            ![]() {
{
 31![]() //与相应的QueryString绑定
                //与相应的QueryString绑定 
 32![]() foreach (string key in queryString.Keys)
                foreach (string key in queryString.Keys)
 33![]() if (queryString[key] != null && !string.IsNullOrEmpty(key))
                    if (queryString[key] != null && !string.IsNullOrEmpty(key))
 34![]() dict[key] = queryString[key];
                        dict[key] = queryString[key];
 35![]() int.TryParse(queryString[currentPageStr], out currentPage);
                int.TryParse(queryString[currentPageStr], out currentPage);
 36![]() }
            }
 37![]() else
            else
 38![]()
![]() 
            ![]() {
{
 39![]() //获取 ~/Page/{page number} 的页号参数
                //获取 ~/Page/{page number} 的页号参数
 40![]() int.TryParse(dict[currentPageStr].ToString(), out currentPage);
                int.TryParse(dict[currentPageStr].ToString(), out currentPage);
 41![]() }
            }
 42![]() if (currentPage <= 0) currentPage = 1;
            if (currentPage <= 0) currentPage = 1;
 43![]() if (totalPages > 1)
            if (totalPages > 1)
 44![]()
![]() 
            ![]() {
{
 45![]() if (currentPage != 1)
                if (currentPage != 1)
 46![]()
![]() 
                ![]() {
{
 47![]() //处理首页连接
                    //处理首页连接  
 48![]() dict[currentPageStr] = 1;
                    dict[currentPageStr] = 1;
 49![]() output.AppendFormat("{0} ", html.RouteLink("首页", dict));
                    output.AppendFormat("{0} ", html.RouteLink("首页", dict));
 50![]() }
                }
 51![]() if (currentPage > 1)
                if (currentPage > 1)
 52![]()
![]() 
                ![]() {
{
 53![]() //处理上一页的连接
                    //处理上一页的连接  
 54![]() dict[currentPageStr] = currentPage - 1;
                    dict[currentPageStr] = currentPage - 1;
 55![]() output.Append(html.RouteLink("上一页", dict));
                    output.Append(html.RouteLink("上一页", dict));
 56![]() }
                }
 57![]() else
                else
 58![]()
![]() 
                ![]() {
{
 59![]() output.Append("上一页");
                    output.Append("上一页");
 60![]() }
                }
 61![]() output.Append(" ");
                output.Append(" ");
 62![]() int currint = 5;
                int currint = 5;
 63![]() for (int i = 0; i <= 10; i++)
                for (int i = 0; i <= 10; i++)
 64![]()
![]() 
                ![]() {
{
 65![]() //一共最多显示10个页码,前面5个,后面5个
                    //一共最多显示10个页码,前面5个,后面5个  
 66![]() if ((currentPage + i - currint) >= 1 && (currentPage + i - currint) <= totalPages)
                    if ((currentPage + i - currint) >= 1 && (currentPage + i - currint) <= totalPages)
 67![]() if (currint == i)
                        if (currint == i)
 68![]()
![]() 
                        ![]() {
{
 69![]() //当前页处理
                            //当前页处理  
 70![]() output.Append(string.Format("[{0}]", currentPage));
                            output.Append(string.Format("[{0}]", currentPage));
 71![]() }
                        }
 72![]() else
                        else
 73![]()
![]() 
                        ![]() {
{
 74![]() //一般页处理
                            //一般页处理 
 75![]() dict[currentPageStr] = currentPage + i - currint;
                            dict[currentPageStr] = currentPage + i - currint;
 76![]() output.Append(html.RouteLink((currentPage + i - currint).ToString(), dict));
                            output.Append(html.RouteLink((currentPage + i - currint).ToString(), dict));
 77![]() }
                        }
 78![]() output.Append(" ");
                    output.Append(" ");
 79![]() }
                }
 80![]() if (currentPage < totalPages)
                if (currentPage < totalPages)
 81![]()
![]() 
                ![]() {
{
 82![]() //处理下一页的链接
                    //处理下一页的链接 
 83![]() dict[currentPageStr] = currentPage + 1;
                    dict[currentPageStr] = currentPage + 1;
 84![]() output.Append(html.RouteLink("下一页", dict));
                    output.Append(html.RouteLink("下一页", dict));
 85![]() }
                }
 86![]() else
                else
 87![]()
![]() 
                ![]() {
{
 88![]() output.Append("下一页");
                    output.Append("下一页");
 89![]() }
                }
 90![]() output.Append(" ");
                output.Append(" ");
 91![]() if (currentPage != totalPages)
                if (currentPage != totalPages)
 92![]()
![]() 
                ![]() {
{
 93![]() dict[currentPageStr] = totalPages;
                    dict[currentPageStr] = totalPages;
 94![]() output.Append(html.RouteLink("末页", dict));
                    output.Append(html.RouteLink("末页", dict));
 95![]() }
                }
 96![]() output.Append(" ");
                output.Append(" ");
 97![]() }
            }
 98![]() output.AppendFormat("{0} / {1}", currentPage, totalPages);//这个统计加不加都行
            output.AppendFormat("{0} / {1}", currentPage, totalPages);//这个统计加不加都行 
 99![]() return output.ToString();
            return output.ToString();
100![]() }
        }
101![]()
102![]() }
    }
103![]() }
}
104![]()
![]()
![]() Code
Code
  1![]() using System;
using System;
  2![]() using System.Collections.Generic;
using System.Collections.Generic;
  3![]() using System.Linq;
using System.Linq;
  4![]() using System.Web;
using System.Web;
  5![]() using System.Web.Mvc;
using System.Web.Mvc;
  6![]() using System.Web.Routing;
using System.Web.Routing;
  7![]() using System.Text;
using System.Text;
  8![]() using System.Web.Mvc.Html;
using System.Web.Mvc.Html;
  9![]()
 10![]() namespace MvcApplication2.Helpers
namespace MvcApplication2.Helpers
 11![]()
![]()
![]() {
{
 12![]() public static class PagerHelper
    public static class PagerHelper
 13![]()
![]() 
    ![]() {
{
 14![]()
![]() /**//// <summary>
        /**//// <summary>  
 15![]() /// 分页Pager显示
        /// 分页Pager显示  
 16![]() /// </summary>
        /// </summary>   
 17![]() /// <param name="html"></param>
        /// <param name="html"></param>  
 18![]() /// <param name="currentPageStr">标识当前页码的QueryStringKey</param>
        /// <param name="currentPageStr">标识当前页码的QueryStringKey</param>   
 19![]() /// <param name="pageSize">每页显示</param>
        /// <param name="pageSize">每页显示</param>  
 20![]() /// <param name="totalCount">总数据量</param>
        /// <param name="totalCount">总数据量</param>  
 21![]() /// <returns></returns>
        /// <returns></returns> 
 22![]() public static string Pager(this HtmlHelper html, string currentPageStr, int pageSize, int totalCount)
        public static string Pager(this HtmlHelper html, string currentPageStr, int pageSize, int totalCount)
 23![]()
![]() 
        ![]() {
{
 24![]() var queryString = html.ViewContext.HttpContext.Request.QueryString;
            var queryString = html.ViewContext.HttpContext.Request.QueryString;
 25![]() int currentPage = 1; //当前页
            int currentPage = 1; //当前页  
 26![]() var totalPages = Math.Max((totalCount + pageSize - 1) / pageSize, 1); //总页数
            var totalPages = Math.Max((totalCount + pageSize - 1) / pageSize, 1); //总页数  
 27![]() var dict = new System.Web.Routing.RouteValueDictionary(html.ViewContext.RouteData.Values);
            var dict = new System.Web.Routing.RouteValueDictionary(html.ViewContext.RouteData.Values);
 28![]() var output = new StringBuilder();
            var output = new StringBuilder();
 29![]() if (!string.IsNullOrEmpty(queryString[currentPageStr]))
            if (!string.IsNullOrEmpty(queryString[currentPageStr]))
 30![]()
![]() 
            ![]() {
{
 31![]() //与相应的QueryString绑定
                //与相应的QueryString绑定 
 32![]() foreach (string key in queryString.Keys)
                foreach (string key in queryString.Keys)
 33![]() if (queryString[key] != null && !string.IsNullOrEmpty(key))
                    if (queryString[key] != null && !string.IsNullOrEmpty(key))
 34![]() dict[key] = queryString[key];
                        dict[key] = queryString[key];
 35![]() int.TryParse(queryString[currentPageStr], out currentPage);
                int.TryParse(queryString[currentPageStr], out currentPage);
 36![]() }
            }
 37![]() else
            else
 38![]()
![]() 
            ![]() {
{
 39![]() //获取 ~/Page/{page number} 的页号参数
                //获取 ~/Page/{page number} 的页号参数
 40![]() if (dict.ContainsKey(currentPageStr))
                if (dict.ContainsKey(currentPageStr))
 41![]() int.TryParse(dict[currentPageStr].ToString(), out currentPage);
                    int.TryParse(dict[currentPageStr].ToString(), out currentPage);
 42![]() }
            }
 43![]()
 44![]() //保留查询字符到下一页
            //保留查询字符到下一页
 45![]() foreach (string key in queryString.Keys)
            foreach (string key in queryString.Keys)
 46![]() dict[key] = queryString[key];
                dict[key] = queryString[key];
 47![]()
 48![]() //如果有需要,保留表单值到下一页 (我暂时不需要, 所以注释掉)
            //如果有需要,保留表单值到下一页 (我暂时不需要, 所以注释掉)
 49![]() //var formValue = html.ViewContext.HttpContext.Request.Form;
            //var formValue = html.ViewContext.HttpContext.Request.Form;
 50![]() //foreach (string key in formValue.Keys)
            //foreach (string key in formValue.Keys)
 51![]() //    if (formValue[key] != null && !string.IsNullOrEmpty(key))
            //    if (formValue[key] != null && !string.IsNullOrEmpty(key))
 52![]() //        dict[key] = formValue[key];
            //        dict[key] = formValue[key]; 
 53![]()
 54![]() if (currentPage <= 0) currentPage = 1;
            if (currentPage <= 0) currentPage = 1;
 55![]() if (totalPages > 1)
            if (totalPages > 1)
 56![]()
![]() 
            ![]() {
{
 57![]() if (currentPage != 1)
                if (currentPage != 1)
 58![]()
![]() 
                ![]() {
{
 59![]() //处理首页连接
                    //处理首页连接  
 60![]() dict[currentPageStr] = 1;
                    dict[currentPageStr] = 1;
 61![]() output.AppendFormat("{0} ", html.RouteLink("首页", dict));
                    output.AppendFormat("{0} ", html.RouteLink("首页", dict));
 62![]() }
                }
 63![]() if (currentPage > 1)
                if (currentPage > 1)
 64![]()
![]() 
                ![]() {
{
 65![]() //处理上一页的连接
                    //处理上一页的连接  
 66![]() dict[currentPageStr] = currentPage - 1;
                    dict[currentPageStr] = currentPage - 1;
 67![]() output.Append(html.RouteLink("上一页", dict));
                    output.Append(html.RouteLink("上一页", dict));
 68![]() }
                }
 69![]() else
                else
 70![]()
![]() 
                ![]() {
{
 71![]() output.Append("上一页");
                    output.Append("上一页");
 72![]() }
                }
 73![]() output.Append(" ");
                output.Append(" ");
 74![]() int currint = 5;
                int currint = 5;
 75![]() for (int i = 0; i <= 10; i++)
                for (int i = 0; i <= 10; i++)
 76![]()
![]() 
                ![]() {
{
 77![]() //一共最多显示10个页码,前面5个,后面5个
                    //一共最多显示10个页码,前面5个,后面5个  
 78![]() if ((currentPage + i - currint) >= 1 && (currentPage + i - currint) <= totalPages)
                    if ((currentPage + i - currint) >= 1 && (currentPage + i - currint) <= totalPages)
 79![]() if (currint == i)
                        if (currint == i)
 80![]()
![]() 
                        ![]() {
{
 81![]() //当前页处理
                            //当前页处理  
 82![]() output.Append(string.Format("[{0}]", currentPage));
                            output.Append(string.Format("[{0}]", currentPage));
 83![]() }
                        }
 84![]() else
                        else
 85![]()
![]() 
                        ![]() {
{
 86![]() //一般页处理
                            //一般页处理 
 87![]() dict[currentPageStr] = currentPage + i - currint;
                            dict[currentPageStr] = currentPage + i - currint;
 88![]() output.Append(html.RouteLink((currentPage + i - currint).ToString(), dict));
                            output.Append(html.RouteLink((currentPage + i - currint).ToString(), dict));
 89![]() }
                        }
 90![]() output.Append(" ");
                    output.Append(" ");
 91![]() }
                }
 92![]() if (currentPage < totalPages)
                if (currentPage < totalPages)
 93![]()
![]() 
                ![]() {
{
 94![]() //处理下一页的链接
                    //处理下一页的链接 
 95![]() dict[currentPageStr] = currentPage + 1;
                    dict[currentPageStr] = currentPage + 1;
 96![]() output.Append(html.RouteLink("下一页", dict));
                    output.Append(html.RouteLink("下一页", dict));
 97![]() }
                }
 98![]() else
                else
 99![]()
![]() 
                ![]() {
{
100![]() output.Append("下一页");
                    output.Append("下一页");
101![]() }
                }
102![]() output.Append(" ");
                output.Append(" ");
103![]() if (currentPage != totalPages)
                if (currentPage != totalPages)
104![]()
![]() 
                ![]() {
{
105![]() dict[currentPageStr] = totalPages;
                    dict[currentPageStr] = totalPages;
106![]() output.Append(html.RouteLink("末页", dict));
                    output.Append(html.RouteLink("末页", dict));
107![]() }
                }
108![]() output.Append(" ");
                output.Append(" ");
109![]() }
            }
110![]() output.AppendFormat("{0} / {1}", currentPage, totalPages);//这个统计加不加都行
            output.AppendFormat("{0} / {1}", currentPage, totalPages);//这个统计加不加都行 
111![]() return output.ToString();
            return output.ToString();
112![]() }
        }
113![]() }
    }
114![]() }
}
115![]()
添加Controller代码:
1![]() public ActionResult Index(int? page)
public ActionResult Index(int? page)
2![]()
![]() 
        ![]() {
{
3![]() if (page == null)
            if (page == null)
4![]() page = 1;
                page = 1;
5![]() return View();
            return View();
6![]() }
        } 
 
aspx页面调用:
1![]() <%=Html.Pager("page", 10, 10020)%>
<%=Html.Pager("page", 10, 10020)%> 
 效果
  ![image image]() 
 
  ![image image]() 
 
  ![image image]() 
 
  ![image image]() 
 
   
  OK这回我们算是解决了这个问题