我使用Asp.net MVC WebAPI支持OData协议进行分页操作的笔记(第二篇)

在阅读这篇文章的时候,我想你已经看完第一篇文章啦·也有可能跟我一样,现在正在使用它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;
        }
    }

下一篇文章,将介绍怎么样使用它,以及项目中需要注意事项与项目源代码下载地址。

时间: 2024-10-12 15:10:22

我使用Asp.net MVC WebAPI支持OData协议进行分页操作的笔记(第二篇)的相关文章

我使用Asp.net MVC WebAPI支持OData协议进行分页操作的笔记(第一篇)

OData协议.多么牛B的技术. 传统的分页写习惯了,最近项目中,用到了 Asp.net WebAPI 2.0来做数据交互接口.至于为什么要使用WebAPI,我想只要是对OData协议有了解的朋友.只要说到WebAPI都会想到这个,如果你想对它有更多的深入了解.可以移步博客园(张善友大师)的介绍. URL(http://www.cnblogs.com/shanyou/archive/2010/03/26/1697316.html) 微软 5.5.2.0 的 System.Web.OData.dl

我使用Asp.net MVC WebAPI支持OData协议进行分页操作的笔记(第三篇)

第三篇笔记,这是自己 Asp.net MVC OData协议 分页解决方案的 最后一记啦.OK,let's go ! 第一件事儿! 第一件事儿,就是下载这个组件了,你可以通过下面提供的附件下载,当然也可以下载源码自己编译一个. 怎么使用它? 在你返回分页数据的Action上加(ODPageResultAttribute)就可以支持返回分页数据了,分页数据返回的格式为json,包含字段如第一篇笔记中提到的分页数据返回对象一致.具体的请参考项目源代码(ODataPQ.Tests\Controller

让Asp.net mvc WebAPI 支持OData协议进行分页查询操作

这是我在用Asp.net mvc WebAPI 支持 OData协议 做分页查询服务时的 个人拙笔. 代码已经开发到oschina上.有兴趣的朋友可以看看,欢迎大家指出不足之处. 看过了园子里的几篇关于ASP.NET MVC WebAPI 支持OData协议的文章,很受启发. 但是对于OData协议下对数据的分页查询,确实没有找到让我满意的东西,可能是个人就这脾气.不喜欢复杂. 对于在 WebAPI 支持OData协议,好处不多讲了,反正,我个人是非常乐意用它来做服务接口之类的. 这篇笔记的主题

.net异步性能测试(包括ASP.NET MVC WebAPI异步方法)

很久没有写博客了,今年做的产品公司这两天刚刚开了发布会,稍微清闲下来,想想我们做的产品还有没有性能优化空间,于是想到了.Net的异步可以优化性能,但到底能够提升多大的比例呢?恰好有一个朋友正在做各种语言的异步性能测试(有关异步和同步的问题,请参考客<AIO与BIO接口性能对比>),于是我今天写了一个C#的测试程序. 首先,建一个 ASP.NET MVC WebAPI项目,在默认的控制器 values里面,增加两个方法: // GET api/values?sleepTime=10 [HttpG

案例:1 Ionic Framework+AngularJS+ASP.NET MVC WebApi Jsonp 移动开发

落叶的庭院扫的一干二净之后,还要轻轻把树摇一下,抖落几片叶子,这才是Wabi Sabi的境界. 介绍:Ionic是移动框架,angularjs这就不用说了,ASP.Net MVC WebApi提供数据源,开放数据接口 快乐学习 Ionic Framework+PhoneGap 手册1-1{创建APP项目}{点击查看} 快乐学习 Ionic Framework+PhoneGap 手册1-2{介绍Header,Content,Footer的使用}{点击查看} 快乐学习 Ionic Framework

asp.net mvc 简易通用自定义Pager实现分页

asp.net mvc 简易通用自定义Pager实现分页 Intro 一个WEB应用程序中经常会用到数据分页,本文将实现一个简单通用的分页组件,包含一个 PagerModel (用来保存页码信息),一个 HtmlHelper 的 Pager 扩展方法和一个 PagedListModel<T> 分页数据模型. PagerModel 分页模型 PagerModel 用来保存分页信息,代码实现如下: 1 /// <summary> 2 /// PagerModel 分页模型 3 ///

OData 协议 asp.net Mvc WebAPI分页笔记

// 针对 OData协议的Mvc WebAPI 2.2 分页插件     ; (function ($, window) {         var tbPQ = function () {         };         // get the length from 'urlAndParamter'         function getCount(urlAndParamter, ok_handler) {             $.ajax(urlAndParamter, {  

ASP.NET MVC WebAPI 资源整理

注:这是收集给公司同事学习的资料,入门级别的. 使用ASP.Net WebAPI构建REST服务(一)——简单的示例 http://blog.csdn.net/mengzhengjie/article/details/52397112 说明:有关WebAPI入门的文章,这是一个系列,对于了解WebAPI其它方面很有帮助. ASP.NET MVC学习之路由篇(1) http://www.cnblogs.com/yaozhenfa/p/asp_net_mvc_route_1.html 说明:有关 M

ASP.NET MVC框架下添加菜单栏及分页项目

原创声明:本文为作者原创,转载请注明出处:http://www.cnblogs.com/DrizzleWorm/p/7274866.html ,谢谢! 我是做前端开发的,之前用C#的三层架构(UI.BLL.DAL)做过一个网站,这是我第一次接触ASP.NET MVC框架,首先给大家分享别人整理的ASP.NET MVC框架的一组教程:http://www.cnblogs.com/powertoolsteam/archive/2015/08/13/4667892.html内容很齐全,我是在先看了其他