Action/ActionResult/ExceptionFilterAttribute(s)
AllowAnonymousAttribute Name cleanup in ReflectionActionDescriptorProvider
This commit is contained in:
parent
457016a6da
commit
4bb66937e3
|
|
@ -19,5 +19,7 @@ namespace Microsoft.AspNet.Mvc
|
||||||
public List<ParameterDescriptor> Parameters { get; set; }
|
public List<ParameterDescriptor> Parameters { get; set; }
|
||||||
|
|
||||||
public List<IFilter> Filters { get; set; }
|
public List<IFilter> Filters { get; set; }
|
||||||
|
|
||||||
|
public bool AllowAnonymous { get; set; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,13 @@
|
||||||
|
using System;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace Microsoft.AspNet.Mvc
|
||||||
|
{
|
||||||
|
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = true, Inherited = true)]
|
||||||
|
public abstract class ActionFilterAttribute : Attribute, IActionFilter, IFilter
|
||||||
|
{
|
||||||
|
public abstract Task Invoke(ActionFilterContext context, Func<ActionFilterContext, Task> next);
|
||||||
|
|
||||||
|
public int Order { get; set; }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,13 @@
|
||||||
|
using System;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace Microsoft.AspNet.Mvc
|
||||||
|
{
|
||||||
|
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = true, Inherited = true)]
|
||||||
|
public abstract class ActionResultFilterAttribute : Attribute, IActionResultFilter, IFilter
|
||||||
|
{
|
||||||
|
public abstract Task Invoke(ActionResultFilterContext context, Func<ActionResultFilterContext, Task> next);
|
||||||
|
|
||||||
|
public int Order { get; set; }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,9 @@
|
||||||
|
using System;
|
||||||
|
|
||||||
|
namespace Microsoft.AspNet.Mvc
|
||||||
|
{
|
||||||
|
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = true, Inherited = true)]
|
||||||
|
public sealed class AllowAnonymousAttribute : Attribute
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,13 @@
|
||||||
|
using System;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace Microsoft.AspNet.Mvc
|
||||||
|
{
|
||||||
|
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = true, Inherited = true)]
|
||||||
|
public abstract class ExceptionFilterAttribute : Attribute, IExceptionFilter, IFilter
|
||||||
|
{
|
||||||
|
public abstract Task Invoke(ExceptionFilterContext context, Func<ExceptionFilterContext, Task> next);
|
||||||
|
|
||||||
|
public int Order { get; set; }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -43,7 +43,10 @@ namespace Microsoft.AspNet.Mvc
|
||||||
|
|
||||||
foreach (var cd in controllerDescriptors)
|
foreach (var cd in controllerDescriptors)
|
||||||
{
|
{
|
||||||
var controllerFilters = GetOrderedFilterAttributes(cd.ControllerTypeInfo);
|
var controllerAttributes = cd.ControllerTypeInfo.GetCustomAttributes(inherit: true).ToArray();
|
||||||
|
var filtersFromController = GetOrderedFilterAttributes(controllerAttributes);
|
||||||
|
|
||||||
|
bool allowAnonymous = IsAnonymous(controllerAttributes);
|
||||||
|
|
||||||
foreach (var methodInfo in cd.ControllerTypeInfo.DeclaredMethods)
|
foreach (var methodInfo in cd.ControllerTypeInfo.DeclaredMethods)
|
||||||
{
|
{
|
||||||
|
|
@ -56,15 +59,19 @@ namespace Microsoft.AspNet.Mvc
|
||||||
|
|
||||||
foreach (var actionInfo in actionInfos)
|
foreach (var actionInfo in actionInfos)
|
||||||
{
|
{
|
||||||
yield return BuildDescriptor(cd, methodInfo, actionInfo, controllerFilters);
|
yield return BuildDescriptor(cd, methodInfo, actionInfo, filtersFromController, allowAnonymous);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private IFilter[] GetOrderedFilterAttributes(MemberInfo memberInfo)
|
private bool IsAnonymous(object[] attributes)
|
||||||
|
{
|
||||||
|
return attributes.OfType<AllowAnonymousAttribute>().Any();
|
||||||
|
}
|
||||||
|
|
||||||
|
private IFilter[] GetOrderedFilterAttributes(object[] attributes)
|
||||||
{
|
{
|
||||||
var attributes = memberInfo.GetCustomAttributes(inherit: true);
|
|
||||||
var filters = attributes.OfType<IFilter>().OrderByDescending(filter => filter.Order);
|
var filters = attributes.OfType<IFilter>().OrderByDescending(filter => filter.Order);
|
||||||
|
|
||||||
return filters.ToArray();
|
return filters.ToArray();
|
||||||
|
|
@ -73,7 +80,8 @@ namespace Microsoft.AspNet.Mvc
|
||||||
private ReflectedActionDescriptor BuildDescriptor(ControllerDescriptor controllerDescriptor,
|
private ReflectedActionDescriptor BuildDescriptor(ControllerDescriptor controllerDescriptor,
|
||||||
MethodInfo methodInfo,
|
MethodInfo methodInfo,
|
||||||
ActionInfo actionInfo,
|
ActionInfo actionInfo,
|
||||||
IFilter[] controllerFilters)
|
IFilter[] controllerFilters,
|
||||||
|
bool allowAnonymous)
|
||||||
{
|
{
|
||||||
var ad = new ReflectedActionDescriptor
|
var ad = new ReflectedActionDescriptor
|
||||||
{
|
{
|
||||||
|
|
@ -107,37 +115,41 @@ namespace Microsoft.AspNet.Mvc
|
||||||
|
|
||||||
ad.Parameters = methodInfo.GetParameters().Select(p => _parameterDescriptorFactory.GetDescriptor(p)).ToList();
|
ad.Parameters = methodInfo.GetParameters().Select(p => _parameterDescriptorFactory.GetDescriptor(p)).ToList();
|
||||||
|
|
||||||
// TODO: add ordering support such that action filters are ahead of controller filters if they have the same order
|
var attributes = methodInfo.GetCustomAttributes(inherit: true).ToArray();
|
||||||
var actionFilters = GetOrderedFilterAttributes(methodInfo);
|
|
||||||
|
|
||||||
ad.Filters = MergeSorted(actionFilters, controllerFilters);
|
// TODO: add ordering support such that action filters are ahead of controller filters if they have the same order
|
||||||
|
var filtersFromAction = GetOrderedFilterAttributes(attributes);
|
||||||
|
|
||||||
|
ad.Filters = MergeSorted(filtersFromAction, controllerFilters);
|
||||||
|
|
||||||
|
ad.AllowAnonymous = allowAnonymous || IsAnonymous(attributes);
|
||||||
|
|
||||||
return ad;
|
return ad;
|
||||||
}
|
}
|
||||||
|
|
||||||
internal List<IFilter> MergeSorted(IFilter[] actionFilters, IFilter[] controllerFilters)
|
private List<IFilter> MergeSorted(IFilter[] filtersFromAction, IFilter[] filtersFromController)
|
||||||
{
|
{
|
||||||
var list = new List<IFilter>();
|
var list = new List<IFilter>();
|
||||||
|
|
||||||
var count = actionFilters.Length + controllerFilters.Length;
|
var count = filtersFromAction.Length + filtersFromController.Length;
|
||||||
|
|
||||||
for (int i = 0, j = 0; i + j < count; )
|
for (int i = 0, j = 0; i + j < count; )
|
||||||
{
|
{
|
||||||
if (i >= actionFilters.Length)
|
if (i >= filtersFromAction.Length)
|
||||||
{
|
{
|
||||||
list.Add(controllerFilters[j++]);
|
list.Add(filtersFromController[j++]);
|
||||||
}
|
}
|
||||||
else if (j >= controllerFilters.Length)
|
else if (j >= filtersFromController.Length)
|
||||||
{
|
{
|
||||||
list.Add(actionFilters[i++]);
|
list.Add(filtersFromAction[i++]);
|
||||||
}
|
}
|
||||||
else if (actionFilters[i].Order >= controllerFilters[j].Order)
|
else if (filtersFromAction[i].Order >= filtersFromController[j].Order)
|
||||||
{
|
{
|
||||||
list.Add(actionFilters[i++]);
|
list.Add(filtersFromAction[i++]);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
list.Add(controllerFilters[j++]);
|
list.Add(filtersFromController[j++]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue