私はAspを使います.NetMVC WebAPI ODataプロトコルによるページング操作をサポートするメモ(第2編)
5931 ワード
この文章を読んでいるうちに、あなたはもう最初の文章を読んだと思います・私と同じかもしれませんが、今使っています.NetWebAPIは私たちのために仕事をしています.サービスページングクエリーインタフェースか、他の操作か、いくつかの小さな問題が発生しました.問題があったら、問題を解決しましょう.△私たち万歳、万歳、万歳!
ちょっと話してNetMVC WebAPIは、Asp.NetMVCベース.すべてのリクエスト処理は、MVCのルーティング規則に従い、リクエストのブロックと処理については、カスタマイズによって継承することができる.
の任意のタグクラスを書き換え、その中の4つのメソッドOnActionExecuted,OnActionExecutedAsync,OnActionExecuting
OnActionExecutingAsyncは、リクエストのブロック、フィルタリングなどを実現します.最後にActionタグを通過するか、Globalを通過する.asaxでグローバル登録を行います.MVCのリクエストブロックとカスタムロジック管理を実現できます.
その廬山の正体を見てください.次のように定義します.
FilterAttributeから継承された抽象クラスであり、同時にIActionFilter、IFIlterの2つのインタフェースが実現されていることがわかります.△もう中に入らないで、興味があれば自分で見てもいいし、ASP.NET MVCの技術書全体を見てもいいです.
以下に、コアコードの一部の実装を示します(System.Web.ODataプロジェクトソースコードのEnableryAttributeオブジェクト定義を参照).
次の記事では、どのように使用するか、プロジェクトの注意点とプロジェクトのソースコードのダウンロードアドレスについて説明します.
ちょっと話してNetMVC WebAPIは、Asp.NetMVCベース.すべてのリクエスト処理は、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の2つのインタフェースが実現されていることがわかります.△もう中に入らないで、興味があれば自分で見てもいいし、ASP.NET MVCの技術書全体を見てもいいです.
以下に、コアコードの一部の実装を示します(System.Web.ODataプロジェクトソースコードのEnableryAttributeオブジェクト定義を参照).
/// <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;
}
}
次の記事では、どのように使用するか、プロジェクトの注意点とプロジェクトのソースコードのダウンロードアドレスについて説明します.