private static List <MethodInfo> RunSelectionFilters(ControllerContext controllerContext, List <MethodInfo> methodInfos) { // remove all methods which are opting out of this request // to opt out, at least one attribute defined on the method must return false List <MethodInfo> matchesWithSelectionAttributes = new List <MethodInfo>(); List <MethodInfo> matchesWithoutSelectionAttributes = new List <MethodInfo>(); foreach (MethodInfo methodInfo in methodInfos) { ICollection <ActionMethodSelectorAttribute> attrs = ReflectedAttributeCache.GetActionMethodSelectorAttributes(methodInfo); if (attrs.Count == 0) { matchesWithoutSelectionAttributes.Add(methodInfo); } else if (attrs.All(attr => attr.IsValidForRequest(controllerContext, methodInfo))) { matchesWithSelectionAttributes.Add(methodInfo); } } // if a matching action method had a selection attribute, consider it more specific than a matching action method // without a selection attribute return((matchesWithSelectionAttributes.Count > 0) ? matchesWithSelectionAttributes : matchesWithoutSelectionAttributes); }
public override IEnumerable <FilterAttribute> GetFilterAttributes(bool useCache) { if (useCache && GetType() == typeof(ReflectedActionDescriptor)) { // Do not look at cache in types derived from this type because they might incorrectly implement GetCustomAttributes return(ReflectedAttributeCache.GetMethodFilterAttributes(MethodInfo)); } return(base.GetFilterAttributes(useCache)); }
internal override IEnumerable <FilterAttribute> GetFilterAttributes(bool useCache) { if (useCache && GetType() == typeof(ReflectedControllerDescriptor)) { // Do not look at cache in types derived from this type because they might incorrectly implement GetCustomAttributes return(ReflectedAttributeCache.GetTypeFilterAttributes(ControllerType)); } return(base.GetFilterAttributes(useCache)); }
internal List <MethodInfo> GetMatchingAliasedMethods(ControllerContext controllerContext, string actionName) { // find all aliased methods which are opting in to this request // to opt in, all attributes defined on the method must return true var methods = from methodInfo in AliasedMethods let attrs = ReflectedAttributeCache.GetActionNameSelectorAttributes(methodInfo) where attrs.All(attr => attr.IsValidName(controllerContext, actionName, methodInfo)) select methodInfo; return(methods.ToList()); }
protected static void RunSelectionFilters( ControllerContext controllerContext, List <MethodInfo> methodInfos ) { // Filter depending on the selection attribute. // Methods with valid selection attributes override all others. // Methods with one or more invalid selection attributes are removed. bool hasValidSelectionAttributes = false; // loop backwards for fastest removal for (int i = methodInfos.Count - 1; i >= 0; i--) { MethodInfo methodInfo = methodInfos[i]; ReadOnlyCollection <ActionMethodSelectorAttribute> attrs = ReflectedAttributeCache.GetActionMethodSelectorAttributesCollection(methodInfo); if (attrs.Count == 0) { // case 1: this method does not have a MethodSelectionAttribute if (hasValidSelectionAttributes) { // if there is already method with a valid selection attribute, remove method without one methodInfos.RemoveAt(i); } } else if (IsValidMethodSelector(attrs, controllerContext, methodInfo)) { // case 2: this method has MethodSelectionAttributes that are all valid // if a matching action method had a selection attribute, consider it more specific than a matching action method // without a selection attribute if (!hasValidSelectionAttributes) { // when the first selection attribute is discovered, remove any items later in the list without selection attributes if (i + 1 < methodInfos.Count) { methodInfos.RemoveFrom(i + 1); } hasValidSelectionAttributes = true; } } else { // case 3: this method has a method selection attribute but it is not valid // remove the method since it is opting out of this request methodInfos.RemoveAt(i); } } }
private static bool IsMatchingAliasedMethod(MethodInfo method, ControllerContext controllerContext, string actionName) { // return if aliased method is opting in to this request // to opt in, all attributes defined on the method must return true ReadOnlyCollection <ActionNameSelectorAttribute> attributes = ReflectedAttributeCache.GetActionNameSelectorAttributes(method); // Caching count is faster for ReadOnlyCollection int attributeCount = attributes.Count; // Performance sensitive, so avoid foreach for (int i = 0; i < attributeCount; i++) { if (!attributes[i].IsValidName(controllerContext, actionName, method)) { return(false); } } return(true); }