• 扩展方法学习发展之路


    大学学习的java,工作后转成了C#,由于工作需要,全力去学习了C#,学习中,相信大家都会有相同的疑惑,在判断一个字符串是否为空的时候总会用到string.IsNullOrEmpty(s)这个方法,最开始就想到了是不是反射,后面才知道这是c#的扩展方法,后面的内容慢慢讲解我对扩展方法由浅到深的理解与用法。

    1:扩展方法的自定义实现,我这里特别用到了判断类型是否为数值类型的方法(可以去比较学习下),里面子定义了4个扩展方法

     1 namespace ConsoleApplication1
     2 {
     3     class Program
     4     {
     5         static void Main(string[] args)
     6         {
     7             var i = 32;  
     8             System.Console.WriteLine(i.GetType().IsNumericType());
     9             System.Console.ReadKey();     
    10         }
    11     }
    12 
    13     public static class TestExtension
    14     {
    15         //老外的代码
    16         public static bool IsNumeric(this Type dataType)
    17         {
    18             if (dataType == null)
    19                 throw new ArgumentNullException("dataType");
    20 
    21             return (dataType == typeof(int)
    22                     || dataType == typeof(double)
    23                     || dataType == typeof(long)
    24                     || dataType == typeof(short)
    25                     || dataType == typeof(float)
    26                     || dataType == typeof(Int16)
    27                     || dataType == typeof(Int32)
    28                     || dataType == typeof(Int64)
    29                     || dataType == typeof(uint)
    30                     || dataType == typeof(UInt16)
    31                     || dataType == typeof(UInt32)
    32                     || dataType == typeof(UInt64)
    33                     || dataType == typeof(sbyte)
    34                     || dataType == typeof(Single)
    35                    );
    36         }
    37         /// <summary>
    38         /// 判断是否为数值类型。
    39         /// </summary>
    40         /// <param name="t">要判断的类型</param>
    41         /// <returns>是否为数值类型</returns>
    42         public static bool IsNumericType(this Type t)
    43         {
    44             var tc = Type.GetTypeCode(t);
    45             return (t.IsPrimitive && t.IsValueType && !t.IsEnum && tc != TypeCode.Char && tc != TypeCode.Boolean) || tc == TypeCode.Decimal;
    46         }
    47 
    48         /// <summary>
    49         /// 判断是否为可空数值类型。
    50         /// </summary>
    51         /// <param name="t">要判断的类型</param>
    52         /// <returns>是否为可空数值类型</returns>
    53         public static bool IsNumericOrNullableNumericType(this Type t)
    54         {
    55             return t.IsNumericType() || (t.IsNullableType() && t.GetGenericArguments()[0].IsNumericType());
    56         }
    57 
    58         /// <summary>
    59         /// 判断是否为可空类型。
    60         /// 注意,直接调用可空对象的.GetType()方法返回的会是其泛型值的实际类型,用其进行此判断肯定返回false。
    61         /// </summary>
    62         /// <param name="t">要判断的类型</param>
    63         /// <returns>是否为可空类型</returns>
    64         public static bool IsNullableType(this Type t)
    65         {
    66             return t.IsGenericType && t.GetGenericTypeDefinition() == typeof(Nullable<>);
    67         }
    68 
    69     }
    70 }

    2:通过上面的列子可能就只能看出它使用上更为便捷而已,但当我接触到Linq,才发现扩展方法的强大,自己也学着参考改造下Linq的构造方法以增加增加所需要的功能

     1 public static class QueryableExtensions
     2     {
     3         public static IQueryable<T> OrderBy<T>(this IQueryable<T> queryable, string propertyName)
     4         {
     5             return QueryableHelper<T>.OrderBy(queryable, propertyName, false);
     6         }
     7         public static IQueryable<T> OrderBy<T>(this IQueryable<T> queryable, string propertyName, bool desc)
     8         {
     9             return QueryableHelper<T>.OrderBy(queryable, propertyName, desc);
    10         }
    11      
    12         static class QueryableHelper<T>
    13         {
    14             //为了缓存表达式树
    15             private static Dictionary<string, LambdaExpression> cache = new Dictionary<string, LambdaExpression>();
    16             public static IQueryable<T> OrderBy(IQueryable<T> queryable, string propertyName, bool   desc)
    17             {
    18 
    19                 dynamic keySelector = GetLambdaExpression(propertyName);
    20                 return desc ? Queryable.OrderByDescending(queryable, keySelector) : Queryable.OrderBy(queryable, keySelector);
    21             }
    22             private static LambdaExpression GetLambdaExpression(string propertyName)
    23             {
    24                 if (cache.ContainsKey(propertyName)) return cache[propertyName];
    25                 var param = Expression.Parameter(typeof(T));
    26                 var body = Expression.Property(param, propertyName);
    27                 var keySelector = Expression.Lambda(body, param);
    28                 cache[propertyName] = keySelector;
    29                 return keySelector;
    30             }
    31         }
    32     }

    4:对于数据库的操作,也可以使用扩展方法,我上篇随笔也说了,项目用了IOC,没有在数据库这块用到扩展方法,这可以参考http://www.cnblogs.com/xiaotuni/archive/2012/05/29/2523683.html

    5:当使用到MVC框架的时候,看到前端的页面使用Html.BeginForm等一些相同格式语法的时候,我马上意识到这就是MVC里面的扩展方法,转而想是否可以自己也写一些扩展方法,方便自己使用,首先我想到前端Table的遍历,分页等,并着手全部实现,并应用于项目中

    Table的遍历,我们在后台写好一个扩展方法类

     1  public static class RazorExtensions
     2     {
     3         public static HelperResult /*List*/ Repeat<T>(this IEnumerable<T> items,
     4             Func<T, HelperResult> template)
     5         {
     6             if (items == null) 
     7                 return new HelperResult(t => t.Write(""));
     8 
     9             return new HelperResult(writer =>
    10             {
    11                 foreach (var item in items)
    12                 {
    13                     template(item).WriteTo(writer);
    14                 }
    15             });
    16         }
    17 }

    前端我们引用他的命名空间,如下方式调用:

    <tbody>
                    @Model.Repeat(
                        @<tr>
                             <td><ahref="/order/catalog/new/@item.ContractNo">@item.ContractNo</a></td>  
                             <td>@item.StrokeNo</td>
                             <td>@item.StrokeDesc</td>                  
                             <td>@item.ContractStatus</td>
                             <td>@item.DeptNo</td>
                             <td>@item.Season</td>
                             <td>@item.SupplierSeries</td>
                             <td>@item.CountryCode</td>
                             <td>@item.ProductDesc</td>
                             <td>@item.DateLastModified</td>
                             <td>@item.CreatedTime.Format()</td>
                         </tr>)
                </tbody>

    分页控件的实现:

    后台:首先我们必须有一个page类

    namespace WebPrint.Web.Mvc.Pager
    {
        public class PagerOptions
        {
            public PagerOptions()
            {
                AutoHide = true;
                PageIndexParameterName = "pageindex";
                NumericPagerItemCount = 10;
                AlwaysShowFirstLastPageNumber = false;
                ShowPrevNext = true;
                NextPageText = "&gt;";
                PrevPageText = "&lt;";
                ShowNumericPagerItems = true;
                ShowFirstLast = true;
                FirstPageText = "&lt;&lt;";
                LastPageText = "&gt;&gt";
                ShowMorePagerItems = true;
                MorePageText = "...";
                ShowDisabledPagerItems = true;
                PagerItemsSeperator = "  ";
                ContainerTagName = "div";
                InvalidPageIndexErrorMessage = "页索引无效";
                PageIndexOutOfRangeErrorMessage = "页索引超出范围";
                MaxPageIndex = 0;
                FirstPageRouteName = null;
            }
            /// <summary>
            /// 首页使用的路由名称(无页索引参数)
            /// </summary>
            public string FirstPageRouteName { get; set; }
            /// <summary>
            /// 当总页数只有一页时是否自动隐藏
            /// </summary>
            public bool AutoHide { get; set; }
            /// <summary>
            /// 页索引超出范围时显示的错误消息
            /// </summary>
            public string PageIndexOutOfRangeErrorMessage { get; set; }
            /// <summary>
            /// 页索引无效时显示的错误消息
            /// </summary>
            public string InvalidPageIndexErrorMessage { get; set; }
            /// <summary>
            /// url中页索引参数的名称
            /// </summary>
            public string PageIndexParameterName { get; set; }
    
            private string _containerTagName;
            /// <summary>
            /// 分页控件html容器标签名,默认为div
            /// </summary>
            public string ContainerTagName
            {
                get
                {
                    return _containerTagName;
                }
                set
                {
                    if (string.IsNullOrEmpty(value))
                        throw new System.ArgumentException("ContainerTagName不能为null或空字符串", "ContainerTagName");
                    _containerTagName = value;
                }
            }
            /// <summary>
            /// whether or not show first and last numeric page number
            /// </summary>
            public bool AlwaysShowFirstLastPageNumber { get; set; }
            /// <summary>
            /// 显示的最大数字页索引按钮数
            /// </summary>
            public int NumericPagerItemCount { get; set; }
            /// <summary>
            /// 是否显示上页和下页
            /// </summary>
            public bool ShowPrevNext { get; set; }
            /// <summary>
            /// 上一页文本
            /// </summary>
            public string PrevPageText { get; set; }
            /// <summary>
            /// 下一页文本
            /// </summary>
            public string NextPageText { get; set; }
            /// <summary>
            /// 是否显示数字页索引按钮及更多页按钮
            /// </summary>
            public bool ShowNumericPagerItems { get; set; }
            /// <summary>
            /// 是否显示第一页和最后一页
            /// </summary>
            public bool ShowFirstLast { get; set; }
            /// <summary>
            /// 第一页文本
            /// </summary>
            public string FirstPageText { get; set; }
            /// <summary>
            /// 最后一页文本
            /// </summary>
            public string LastPageText { get; set; }
            /// <summary>
            /// 是否显示更多页按钮
            /// </summary>
            public bool ShowMorePagerItems { get; set; }
            /// <summary>
            /// 更多页按钮文本
            /// </summary>
            public string MorePageText { get; set; }
            /// <summary>
            /// 包含分页控件的父容器标签的ID
            /// </summary>
            public string Id { get; set; }
            /// <summary>
            /// CSS样式类
            /// </summary>
            public string CssClass { get; set; }
            /// <summary>
            /// whether or not show disabled navigation buttons
            /// </summary>
            public bool ShowDisabledPagerItems { get; set; }
            /// <summary>
            /// 分页元素之间的分隔符,默认为两个html空格(  )
            /// </summary>
            public string PagerItemsSeperator { get; set; }
            /// <summary>
            /// 限制显示的最大页数,默认值为0,即根据总记录数算出的总页数
            /// </summary>
            public int MaxPageIndex { get; set; }
        }
    }

    2个生成分页控件HTML代码的类

    using System;
    using System.Web.Mvc;
    using System.Web.Routing;
    using WebPrint.Model.Helper;
    
    namespace WebPrint.Web.Mvc.Pager
    {
        public static class PagerHelper
        {
            #region Html Pager
    
            private static MvcHtmlString Pager(this HtmlHelper helper, int totalItemCount, int pageSize, int pageIndex,
                string actionName, string controllerName,
                PagerOptions pagerOptions, string routeName, object routeValues, object htmlAttributes)
            {
                var totalPageCount = (int) Math.Ceiling(totalItemCount/(double) pageSize);
                var builder = new PagerBuilder
                    (
                    helper,
                    actionName,
                    controllerName,
                    totalItemCount,
                    totalPageCount,
                    pageIndex,
                    pageSize,
                    pagerOptions,
                    routeName,
                    new RouteValueDictionary(routeValues),
                    new RouteValueDictionary(htmlAttributes)
                    );
                return builder.RenderPager();
            }
    
            public static MvcHtmlString Pager(this HtmlHelper helper, IPagedList pagedList, PagerOptions pagerOptions)
            {
                //if (pagedList == null)
                //    return Pager(helper, pagerOptions, null);
                return Pager(helper, pagedList.RecordsCount, pagedList.PageSize, pagedList.PageIndex, null, null,
                    pagerOptions, null, null, null);
            }
    
            #endregion
        }
    }
    
    
    /*
     ASP.NET MvcPager 分页组件
     Copyright@杨涛Webdiyer (http://www.webdiyer.com)
     Source code released under Ms-PL license
     */
    
    using System;
    using System.Collections.Generic;
    using System.Globalization;
    using System.Text;
    using System.Web;
    using System.Web.Mvc;
    using System.Web.Routing;
    
    namespace WebPrint.Web.Mvc.Pager
    {
        internal class PagerBuilder
        {
            private readonly HtmlHelper html;
            private readonly string actionName;
            private readonly string controllerName;
            private readonly int totalPageCount = 1;
            private readonly int totalRecordCount = 1;
            private readonly int pageIndex;
            private readonly int pageSize;
            private readonly PagerOptions pagerOptions;
            private readonly RouteValueDictionary routeValues;
            private readonly string routeName;
            private readonly int startPageIndex = 1;
            private readonly int endPageIndex = 1;
            private IDictionary<string, object> htmlAttributes;
    
            private const string CopyrightText =
                "
    <!--MvcPager v2.0 for ASP.NET MVC 4.0+ © 2009-2013 Webdiyer (http://www.webdiyer.com)-->
    ";
    
            /// <summary>
            /// 适用于PagedList为null时
            /// </summary>
            //internal PagerBuilder(HtmlHelper html,PagerOptions pagerOptions, IDictionary<string, object> htmlAttributes)
            //{
            //    if (pagerOptions == null)
            //        pagerOptions = new PagerOptions();
            //    this.html = html;
            //    this.pagerOptions = pagerOptions;
            //    this.htmlAttributes = htmlAttributes;
            //}
            internal PagerBuilder(HtmlHelper html, string actionName, string controllerName, int totalRecordCount,
                int totalPageCount, int pageIndex, int pageSize, PagerOptions pagerOptions, string routeName,
                RouteValueDictionary routeValues,
                IDictionary<string, object> htmlAttributes)
            {
                if (pagerOptions == null)
                    pagerOptions = new PagerOptions();
                this.html = html;
                this.actionName = actionName;
                this.controllerName = controllerName;
                this.totalRecordCount = totalRecordCount;
                if (pagerOptions.MaxPageIndex == 0 || pagerOptions.MaxPageIndex > totalPageCount)
                    this.totalPageCount = totalPageCount;
                else
                    this.totalPageCount = pagerOptions.MaxPageIndex;
                this.pageIndex = pageIndex;
                this.pageSize = pageSize;
                this.pagerOptions = pagerOptions;
                this.routeName = routeName;
                this.routeValues = routeValues;
                this.htmlAttributes = htmlAttributes;
                // start page index
                startPageIndex = pageIndex - (pagerOptions.NumericPagerItemCount/2);
                if (startPageIndex + pagerOptions.NumericPagerItemCount > this.totalPageCount)
                    startPageIndex = this.totalPageCount + 1 - pagerOptions.NumericPagerItemCount;
                if (startPageIndex < 1)
                    startPageIndex = 1;
                // end page index
                endPageIndex = startPageIndex + this.pagerOptions.NumericPagerItemCount - 1;
                if (endPageIndex > this.totalPageCount)
                    endPageIndex = this.totalPageCount;
            }
    
            private void AddPrevious(ICollection<PagerItem> results)
            {
                var item = new PagerItem(pagerOptions.PrevPageText, pageIndex - 1, pageIndex == 1, PagerItemType.PrevPage);
                if (!item.Disabled || (item.Disabled && pagerOptions.ShowDisabledPagerItems))
                    results.Add(item);
            }
    
            private void AddFirst(ICollection<PagerItem> results)
            {
                var item = new PagerItem(pagerOptions.FirstPageText, 1, pageIndex == 1, PagerItemType.FirstPage);
                //只有导航按钮未被禁用,或导航按钮被禁用但ShowDisabledPagerItems=true时才添加
                if (!item.Disabled || (item.Disabled && pagerOptions.ShowDisabledPagerItems))
                    results.Add(item);
            }
    
            private void AddMoreBefore(ICollection<PagerItem> results)
            {
                if (startPageIndex > 1 && pagerOptions.ShowMorePagerItems)
                {
                    var index = startPageIndex - 1;
                    if (index < 1) index = 1;
                    var item = new PagerItem(pagerOptions.MorePageText, index, false, PagerItemType.MorePage);
                    results.Add(item);
                }
            }
    
            private void AddPageNumbers(ICollection<PagerItem> results)
            {
                for (var pageIndex = startPageIndex; pageIndex <= endPageIndex; pageIndex++)
                {
                    var text = pageIndex.ToString(CultureInfo.InvariantCulture);
                    //if (pageIndex == this.pageIndex && !string.IsNullOrEmpty(pagerOptions.CurrentPageNumberFormatString))
                    //    text = String.Format(pagerOptions.CurrentPageNumberFormatString, text);
                    //else if (!string.IsNullOrEmpty(pagerOptions.PageNumberFormatString))
                    //    text = String.Format(pagerOptions.PageNumberFormatString, text);
                    var item = new PagerItem(text, pageIndex, false, PagerItemType.NumericPage);
                    results.Add(item);
                }
            }
    
            private void AddMoreAfter(ICollection<PagerItem> results)
            {
                if (endPageIndex < totalPageCount)
                {
                    var index = startPageIndex + pagerOptions.NumericPagerItemCount;
                    if (index > totalPageCount)
                    {
                        index = totalPageCount;
                    }
                    var item = new PagerItem(pagerOptions.MorePageText, index, false, PagerItemType.MorePage);
                    results.Add(item);
                }
            }
    
            private void AddNext(ICollection<PagerItem> results)
            {
                var item = new PagerItem(pagerOptions.NextPageText, pageIndex + 1, pageIndex >= totalPageCount,
                    PagerItemType.NextPage);
                if (!item.Disabled || (item.Disabled && pagerOptions.ShowDisabledPagerItems))
                    results.Add(item);
            }
    
            private void AddLast(ICollection<PagerItem> results)
            {
                var item = new PagerItem(pagerOptions.LastPageText, totalPageCount, pageIndex >= totalPageCount,
                    PagerItemType.LastPage);
                if (!item.Disabled || (item.Disabled && pagerOptions.ShowDisabledPagerItems))
                    results.Add(item);
            }
    
            /// <summary>
            /// 根据页索引生成分页导航Url
            /// </summary>
            /// <param name="pageIndex">要生成导航链接的页索引</param>
            /// <returns>分页导航链接Url</returns>
            private string GenerateUrl(int pageIndex)
            {
                ViewContext viewContext = html.ViewContext;
                //若要生成url的页索引小于1或大于总页数或等于当前页索引时,无需生成分页导航链接
                if (pageIndex > totalPageCount || pageIndex == this.pageIndex)
                    return null;
                var routeValues1 = new RouteValueDictionary(viewContext.RouteData.Values);
                AddQueryStringToRouteValues(routeValues1, viewContext);
                if (this.routeValues != null && this.routeValues.Count > 0)
                {
                    foreach (var de in this.routeValues)
                    {
                        if (!routeValues1.ContainsKey(de.Key))
                        {
                            routeValues1.Add(de.Key, de.Value);
                        }
                        else
                        {
                            routeValues1[de.Key] = de.Value; //手动添加的RouteValues具有高优先级
                        }
                    }
                }
                var pageValue = viewContext.RouteData.Values[pagerOptions.PageIndexParameterName];
                string routeName = this.routeName;
                // 设置Route Value中的分页导航Url参数值,pageIndex为0时生成适用于脚本的导航链接
                if (pageIndex == 0)
                    routeValues1[pagerOptions.PageIndexParameterName] = "__" + pagerOptions.PageIndexParameterName + "__";
                else
                {
                    if (pageIndex == 1)
                    {
                        if (!string.IsNullOrWhiteSpace(pagerOptions.FirstPageRouteName))
                            //如果显式指定了FirstPageRouteName,则使用此Route
                        {
                            routeName = pagerOptions.FirstPageRouteName;
                            routeValues1.Remove(pagerOptions.PageIndexParameterName); //去除页索引参数
                            viewContext.RouteData.Values.Remove(pagerOptions.PageIndexParameterName);
                        }
                        else
                        {
                            var curRoute = viewContext.RouteData.Route as Route;
                            //判断当前Route是否为Route类型,如果是,则判断该Route中页索引参数默认值是否为UrlParameter.Optional,或页索引参数是否存在于该Route Url的参数列表中,如果参数默认值为UrlParameter.Optional或分页参数名不存在于Route Url参数中,则从当前的RouteValue列表中去除该参数
                            if (curRoute != null &&
                                (curRoute.Defaults[pagerOptions.PageIndexParameterName] == UrlParameter.Optional ||
                                 !curRoute.Url.Contains("{" + pagerOptions.PageIndexParameterName + "}")))
                            {
                                routeValues1.Remove(pagerOptions.PageIndexParameterName); //去除页索引参数
                                viewContext.RouteData.Values.Remove(pagerOptions.PageIndexParameterName);
                            }
                            else
                            {
                                routeValues1[pagerOptions.PageIndexParameterName] = pageIndex;
                            }
                        }
                    }
                    else
                    {
                        routeValues1[pagerOptions.PageIndexParameterName] = pageIndex;
                    }
                }
                var routes = html.RouteCollection;
                string url;
                if (!string.IsNullOrEmpty(routeName))
                    url = UrlHelper.GenerateUrl(routeName, actionName, controllerName, routeValues1, routes,
                        viewContext.RequestContext, false);
                else
                    url = UrlHelper.GenerateUrl(null, actionName, controllerName, routeValues1, routes,
                        viewContext.RequestContext, false);
                if (pageValue != null)
                    viewContext.RouteData.Values[pagerOptions.PageIndexParameterName] = pageValue;
                return url;
            }
    
            /// <summary>
            /// 生成最终的分页Html代码
            /// </summary>
            /// <returns></returns>
            internal MvcHtmlString RenderPager()
            {
                //return null if total page count less than or equal to 1
                if (totalPageCount <= 1 && pagerOptions.AutoHide)
                    return MvcHtmlString.Create(CopyrightText);
                //Display error message if pageIndex out of range
                if ((pageIndex > totalPageCount && totalPageCount > 0) || pageIndex < 1)
                {
                    return
                        MvcHtmlString.Create(string.Format("{0}<div style="color:red;font-weight:bold">{1}</div>{0}",
                            CopyrightText, pagerOptions.PageIndexOutOfRangeErrorMessage));
                }
    
                var pagerItems = new List<PagerItem>();
                //First page
                if (pagerOptions.ShowFirstLast)
                    AddFirst(pagerItems);
                // Prev page
                if (pagerOptions.ShowPrevNext)
                    AddPrevious(pagerItems);
                if (pagerOptions.ShowNumericPagerItems)
                {
                    if (pagerOptions.AlwaysShowFirstLastPageNumber && startPageIndex > 1)
                        pagerItems.Add(new PagerItem("1", 1, false, PagerItemType.NumericPage));
                    // more page before numeric page buttons
                    if (pagerOptions.ShowMorePagerItems &&
                        ((!pagerOptions.AlwaysShowFirstLastPageNumber && startPageIndex > 1) ||
                         (pagerOptions.AlwaysShowFirstLastPageNumber && startPageIndex > 2)))
                        AddMoreBefore(pagerItems);
                    // numeric page
                    AddPageNumbers(pagerItems);
                    // more page after numeric page buttons
                    if (pagerOptions.ShowMorePagerItems &&
                        ((!pagerOptions.AlwaysShowFirstLastPageNumber && endPageIndex < totalPageCount) ||
                         (pagerOptions.AlwaysShowFirstLastPageNumber && totalPageCount > endPageIndex + 1)))
                        AddMoreAfter(pagerItems);
                    if (pagerOptions.AlwaysShowFirstLastPageNumber && endPageIndex < totalPageCount)
                        pagerItems.Add(new PagerItem(totalPageCount.ToString(CultureInfo.InvariantCulture), totalPageCount,
                            false,
                            PagerItemType.NumericPage));
                }
                // Next page
                if (pagerOptions.ShowPrevNext)
                    AddNext(pagerItems);
                //Last page
                if (pagerOptions.ShowFirstLast)
                    AddLast(pagerItems);
                var sb = new StringBuilder();
    
                foreach (PagerItem item in pagerItems)
                {
                    sb.Append(GeneratePagerElement(item));
                }
    
                var tb = new TagBuilder(pagerOptions.ContainerTagName);
                if (!string.IsNullOrEmpty(pagerOptions.Id))
                    tb.GenerateId(pagerOptions.Id);
                if (!string.IsNullOrEmpty(pagerOptions.CssClass))
                    tb.AddCssClass(pagerOptions.CssClass);
                tb.MergeAttributes(htmlAttributes, true);
                sb.Length -= pagerOptions.PagerItemsSeperator.Length;
    
                var startRecords = ((pageIndex - 1)*pageSize) + 1;
                var endRecords = pageIndex*pageSize;
                if (endRecords > totalRecordCount)
                    endRecords = totalRecordCount;
    
                var recordsCountText =
                    string.Format("<span class="summary">{0}&nbsp;-&nbsp;{1},&nbsp;{2}&nbsp;records</span>",
                        startRecords, endRecords, totalRecordCount);
                tb.InnerHtml = sb.ToString() + recordsCountText;
    
                return
                    MvcHtmlString.Create(CopyrightText + /*pagerScript +*/ tb.ToString(TagRenderMode.Normal) + CopyrightText);
            }
    
            private MvcHtmlString GeneratePagerElement(PagerItem item)
            {
                //pager item link
                string url = GenerateUrl(item.PageIndex);
                if (item.Disabled) //first,last,next or previous page
                    return CreateWrappedPagerElement(item,
                        String.Format("<a class="disabled" disabled="disabled">{0}</a>", item.Text));
                return CreateWrappedPagerElement(item,
                    string.IsNullOrEmpty(url)
                        ? HttpUtility.HtmlEncode(item.Text)
                        : String.Format("<a href="{0}">{1}</a>", url, item.Text));
            }
    
            private MvcHtmlString CreateWrappedPagerElement(PagerItem item, string el)
            {
                string navStr = el;
                switch (item.Type)
                {
                    case PagerItemType.FirstPage:
                    case PagerItemType.LastPage:
                    case PagerItemType.NextPage:
                    case PagerItemType.PrevPage:
                        break;
                    case PagerItemType.MorePage:
                        break;
                    case PagerItemType.NumericPage:
                        if (item.PageIndex == pageIndex)
                        {
                            navStr = string.Format("<a href="javascript:void(0);" class="current">{0}</a>", el);
                        }
                        break;
                }
                return MvcHtmlString.Create(navStr + pagerOptions.PagerItemsSeperator);
            }
    
            private void AddQueryStringToRouteValues(RouteValueDictionary routeValues, ViewContext viewContext)
            {
                if (routeValues == null)
                    routeValues = new RouteValueDictionary();
                var rq = viewContext.HttpContext.Request.QueryString;
                if (rq != null && rq.Count > 0)
                {
                    var invalidParams = new[]
                    {"x-requested-with", "xmlhttprequest", pagerOptions.PageIndexParameterName.ToLower()};
                    foreach (string key in rq.Keys)
                    {
                        // 添加url参数到路由中
                        if (!string.IsNullOrEmpty(key) && Array.IndexOf(invalidParams, key.ToLower()) < 0)
                        {
                            var kv = rq[key];
                            routeValues[key] = kv;
                        }
                    }
                }
            }
        }
    }

    使用扩展方法:

    public static MvcHtmlString Paginaton(this HtmlHelper helper, IPagedList pagedList)
            {
                var pagerOptions = new PagerOptions
                {
                    PageIndexParameterName = "page",
                    CssClass = "pagination",
                    ShowFirstLast = false,
                    AlwaysShowFirstLastPageNumber = true,
                    ShowMorePagerItems = true,
                    NumericPagerItemCount = 5,
                    PagerItemsSeperator = string.Empty,
                };
    
                return helper.Pager(pagedList, pagerOptions);
            }

    前端直接引用调用:

    <div class="pagination_div">
       @Html.Paginaton(Model)
    </div>

    总结:相对于鹤冲天大哥的见解,我对于扩张方法的使用差的太远,但一般的场景也可以用到扩展方法的地方都还是可以轻松应对,所以我们平常就该对深入的学习认识他,才能在后面应用自如

    努力吧少年
  • 相关阅读:
    兼容IE的滚动条自定义样式
    vue从入门到开发--4--处理http请求
    vue从入门到开发--3-基础语法
    Oracle 扩容表空间
    Oracle 整库备份还原
    Oracle 相关命令
    更改mysql数据库根目录
    关于文件系统
    挂载iscsi存储
    挂载nfs存储
  • 原文地址:https://www.cnblogs.com/jameswenhe/p/4544217.html
Copyright © 2020-2023  润新知