您好,登錄后才能下訂單哦!
在閱讀這篇文章的時候,我想你已經看完第一篇文章啦·也有可能跟我一樣,現在正在使用它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<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; } }
下一篇文章,將介紹怎么樣使用它,以及項目中需要注意事項與項目源代碼下載地址。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。