internal static IEnumerable <FilterAttribute> RemoveOverriddenFilters(IEnumerable <FilterAttribute> filters) { // If an attribute is declared on both the controller and on an action method and that attribute's // type has AllowMultiple = false (which is the default for attributes), we should ignore the attributes // declared on the controller. The CLR's reflection implementation follows a similar algorithm when it // encounters an overridden virtual method where both the base and the override contain some // AllowMultiple = false attribute. // Key = attribute type // Value = -1 if AllowMultiple true, last index of this attribute type if AllowMultiple false Dictionary <Type, int> attrsIndexes = new Dictionary <Type, int>(); FilterAttribute[] filtersList = filters.ToArray(); for (int i = 0; i < filtersList.Length; i++) { FilterAttribute filter = filtersList[i]; Type filterType = filter.GetType(); int lastIndex; if (attrsIndexes.TryGetValue(filterType, out lastIndex)) { if (lastIndex >= 0) { // this filter already exists and AllowMultiple = false, so clear last entry filtersList[lastIndex] = null; attrsIndexes[filterType] = i; } } else { // not found - add to dictionary // exactly one AttributeUsageAttribute will always be present bool allowMultiple = _allowMultiplAttributesCache.IsMultiUseAttribute(filterType); attrsIndexes[filterType] = (allowMultiple) ? -1 : i; } } // any duplicated attributes have now been nulled out, so just return remaining attributes return(filtersList.Where(attr => attr != null)); }
/// <summary> /// Composes the attributes. /// </summary> /// <param name="attributes">The attributes.</param> void ComposeAttributes(FilterAttribute[] attributes) { CompositionProvider.Current.ComposeParts(attributes); }
void ComposeAttributes(FilterAttribute[] attributes) { foreach (var attribute in attributes) CompositionProvider.Current.SatisfyImports(attribute); }