我使用Asp.net MVC WebAPI支援OData協議進行分頁操作的筆記(第二篇)

來源:互聯網
上載者:User

標籤:odata分頁 webapi分頁 asp.net webapi


    在閱讀這篇文章的時候,我想你已經看完第一篇文章啦·也有可能跟我一樣,現在正在使用它Asp.net WebAPI為我們幹活兒。可能是服務分頁查詢介面,也可能是其它操作,遇到了一些小問題。有問題,那咱就來解決問題吧!(碼農萬歲,萬歲,萬萬歲!)


    扯兩句,Asp.net MVC WebAPI,是建立在Asp.net MVC基礎上的。所有的請求處理,都遵循MVC的路由規則,對於請求的攔截與處理,都可以通過自訂繼承自

System.Web.Http.Filters.ActionFilterAttribute

的任意標記類,然後重寫裡面的4個方法OnActionExecuted,OnActionExecutedAsync,OnActionExecuting

OnActionExecutingAsync 來實現對請求的攔截,過濾等等。最後通過Action標記,或者通 Global.asax 中進行全域註冊。就可以實現MVC的請求攔截與自訂的邏輯管理了。


看看它的廬山真面目。定義如下:

public abstract class ActionFilterAttribute : FilterAttribute, IActionFilter, IFilter

可以看到,它是一個抽象類別,繼承自FilterAttribute,同時實現了IActionFilter,IFilter兩個介面。(不再往裡面扒了,有興趣你可以自己瞧瞧,也可以整本ASP.NET MVC的技術書看看。)

    

下面是部分核心代碼的實現(參考:System.Web.OData項目源碼的EnableQueryAttribute對象定義)

        /// <summary>    /// 標記Action返回結果為分頁資料對象。    /// Action本身必須返回IQueryable&lt;T>    /// -------------------------------------    /// add by hotboy 2015-5-14 11:32:27    /// </summary>    [AttributeUsage(AttributeTargets.Method, AllowMultiple = true)]    public class ODataPagedAttribute : System.Web.Http.Filters.ActionFilterAttribute{                private const char CommaSeparator = ‘,‘;        private const string PageSizeKey = "$pagesize";        private const int DefaultPageSize = 20;        // validation settings        private ODataValidationSettings _validationSettings;        private string _allowedOrderByProperties;        // query settings        private ODataQuerySettings _querySettings;        /// <summary>        /// Enables a controller action to support OData query parameters.        /// </summary>        public ODataPagedAttribute()        {            _validationSettings = new ODataValidationSettings();            _querySettings = new ODataQuerySettings();        }        //... more than code here ....//        }        //    // IQeruyable靜態方法,參考:System.Web.OData.Extension的QueryableExtensions    // 用於查詢分頁資料以及資料記錄總數。    public class QueryableExtensions    {        private static MethodInfo _limitResultsGenericMethod = typeof(QueryableExtensions).GetMethod("LimitResults");        internal static IQueryable LimitResults(IQueryable queryable, int limit, out bool resultsLimited, out int total)        {            MethodInfo genericMethod = _limitResultsGenericMethod.MakeGenericMethod(queryable.ElementType);            object[] args = new object[] { queryable, limit, null, null };            IQueryable results = genericMethod.Invoke(null, args) as IQueryable;            resultsLimited = (bool)args[2];            total = (int)args[3];            return results;        }        /// <summary>        /// Limits the query results to a maximum number of results.        /// </summary>        /// <typeparam name="T">The entity CLR type</typeparam>        /// <param name="queryable">The queryable to limit.</param>        /// <param name="limit">The query result limit.</param>        /// <param name="resultsLimited"><c>true</c> if the query results were limited; <c>false</c> otherwise</param>        /// <returns>The limited query results.</returns>                public static IQueryable<T> LimitResults<T>(IQueryable<T> queryable, int limit, out bool resultsLimited, out int total)        {            total = queryable.Count();            TruncatedCollection<T> truncatedCollection = new TruncatedCollection<T>(queryable, limit);            resultsLimited = truncatedCollection.IsTruncated;            return truncatedCollection.AsQueryable();        }    }        // Type管理輔助Helper    internal static class TypeHelper {        internal static Type GetImplementedIEnumerableType(Type type)        {            // get inner type from Task<T>            if (type.IsGenericType && type.GetGenericTypeDefinition() == typeof(Task<>))            {                type = type.GetGenericArguments().First();            }            if (type.IsGenericType && type.IsInterface &&                (type.GetGenericTypeDefinition() == typeof(IEnumerable<>) ||                 type.GetGenericTypeDefinition() == typeof(IQueryable<>)))            {                // special case the IEnumerable<T>                return GetInnerGenericType(type);            }            else            {                // for the rest of interfaces and strongly Type collections                Type[] interfaces = type.GetInterfaces();                foreach (Type interfaceType in interfaces)                {                    if (interfaceType.IsGenericType &&                        (interfaceType.GetGenericTypeDefinition() == typeof(IEnumerable<>) ||                         interfaceType.GetGenericTypeDefinition() == typeof(IQueryable<>)))                    {                        // special case the IEnumerable<T>                        return GetInnerGenericType(interfaceType);                    }                }            }            return null;        }        private static Type GetInnerGenericType(Type interfaceType)        {            // Getting the type T definition if the returning type implements IEnumerable<T>            Type[] parameterTypes = interfaceType.GetGenericArguments();            if (parameterTypes.Length == 1)            {                return parameterTypes[0];            }            return null;        }    }


下一篇文章,將介紹怎麼樣使用它,以及項目中需要注意事項與項目原始碼。

本文出自 “傻帽” 部落格,請務必保留此出處http://hotboy.blog.51cto.com/8826994/1651277

我使用Asp.net MVC WebAPI支援OData協議進行分頁操作的筆記(第二篇)

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.