During the execution of the Actioninvoker action, there is an important work in addition to the execution of the action method through the use of Actiondescriptor, as well as the previous model binding and validation, That is the execution of the associated filter (filter). The ASP.net MVC filter is a design based on AOP (aspect-oriented programming) where we implement some of the non-business logic in the appropriate filter and then apply it to the corresponding action method in a crosscutting (crosscutting) way. These filters are automatically executed before and after the action method executes. asp.net MVC provides four types of filters (Authorizationfilter, Actionfilter, Resultfilter, and Exceptionfilter). They correspond to the corresponding filter interfaces (Iauthorizationfilter, Iactionfilter, Iresultfilter, and Iexceptionfilter).
One, Filter
Although the four types of filters provided by ASP.net MVC have their respective implementations, all filters are represented by filter types that have the following definitions for the provider system of the filters. The core of the filter is the instance property, because it represents the object that really implements the filtering function, which implements one or more interfaces based on the four filter types mentioned above.
1:public class Filter
2: {
3: Public const INT defaultorder =-1;
4: Public Filter (object instance, filterscope scope, int. order);
5:
6: Public object Instance {get; protected set;
7: Public int order {get; protected set;}
8: Public filterscope Scope {get; protected set;}
9:}
10:
11:public enum Filterscope
12: {
Action = 30,
Controller = 20,
: 0,
Global = 10,
Last = 100
18:}
Note: due to System.Web.Mvc.Filter and the realization of Iauthorizationfilter, Iactionfilter, The types of Iresultfilter and iexceptionfilter can be called "filters," and in order to avoid confusion, we use English "filter" and Chinese "filters" to represent them separately without making a clear explanation.
The order and scope properties of the filter ultimately determine the sequence in which the filters are executed. The smaller the value of the order attribute, the higher the priority of execution, the default value of 1 (corresponding to the constant Defaultorder defined in filter). If two filter has the same order attribute value, the scope property ultimately determines which is executed first. The Scope property type of filter is an enumeration of type Filterscope. The enumeration represents the scope where the filter is applied, and the action and controller represent the action method and the Controller class level; First and last means that you want to be executed as the primary and final filter The global represents a globally filter.
With the code snippet above, we can see that the 5 enumeration options for Filterscope are set to a value that determines the order in which the filter is executed, with a smaller enumeration value being prioritized. From the definition of filterscope, it can be concluded that for multiple filter with the same order attribute value, the filter applied on the controller has a higher execution priority than the filter applied on the action method. And a global filter has a higher execution priority than filter based on action.
Second, Filterprovider
The supply mechanism of the filter is similar to the one we introduced before, based on Modelbinder and Modelvalidator, and is provided by the corresponding provider. The Filterprovider that provides the filter implements the interface Ifilterprovider, as shown in the following code fragment. The interface defines a unique method Getfilters gets a collection of filter objects based on the specified controller context and the Actiondescriptor object that describes the target action.
1:public Interface Ifilterprovider
2: {
3: ienumerable<filter> getfilters (controllercontext controllercontext, Actiondescriptor ActionDescriptor );
4:}
We can register by static type Filterproviders or get the filterprovider used by the current application. As shown in the following code snippet, Filterproviders has a read-only property providers of type Filterprovidercollection, representing a list of filterprovider that is used within the scope of the entire Web application. A filterprovidercollection is a collection of element type Ifilterprovider, Getfilters method is used or the filter object provided by all Filterprovider objects in the collection.
1:public Static Class Filterproviders
2: {
3: Public static filterprovidercollection Providers {get;}
4:}
5:
6:public class Filterprovidercollection:collection<ifilterprovider>
7: {
8:
9: //other Members
Public ienumerable<filter> getfilters (controllercontext controllercontext, Actiondescriptor Actiondescriptor);
11:}
asp.net mvc provides three native Filterprovider, namely Filterattributefilterprovider, Controllerinstancefilterprovider and Globalfiltercollection, and then we'll introduce them separately.
Iii. FilterAttribute and Filterattributefilterprovider
We typically define filters as attributes to be applied to controller types or action methods declaratively, while abstract type FilterAttribute is the base class for all filters. As shown in the following code fragment, the FilterAttribute feature implements the Imvcfilter interface, which defines the order and AllowMultiple two read-only properties. Used to control the order in which filters are executed, and for multiple homogeneous filters to be applied to the same target element (class or method) at the same time.
1: [AttributeUsage (AttributeTargets.Method | AttributeTargets.Class, Inherited=true, Allowmultiple=false)]
2:public abstract class Filterattribute:attribute, Imvcfilter
3: {
4: protected FilterAttribute ();
5:
6: Public bool AllowMultiple {get;}
7: Public int Order {get; set;}
8:}
9:
10:public Interface Imvcfilter
11: {
: bool AllowMultiple {get;}
int order {get;}
14:}
From the definition of the AttributeUsageAttribute applied to FilterAttribute, it can be seen that the attribute can be applied to types and methods, which means that filters can generally be applied to the controller type and the action method. The read-only property AllowMultiple actually returns the AttributeUsageAttribute attribute with the same name, which we can see by default for this property value of false.
Both Controllerdescriptor and actiondescriptor that describe Controller and action implement the ICustomAttributeProvider interface. We can use them directly to get all the features that apply to the corresponding controller type or action method including FilterAttribute. In fact, these two description types provide a separate method getfilterattributes specifically used to get a list of filterattribute attributes. As the following code fragment shows, the method has a Boolean-type parameter UseCache that indicates whether the parsed FilterAttribute feature needs to be cached to mitigate the performance impact of frequent reflection operations.
1:public abstract class Controllerdescriptor:icustomattributeprovider, iuniquelyidentifiable
2: {
3: //other Members
4: Public virtual ienumerable<filterattribute> getfilterattributes (bool usecache);
5:}
6:public abstract class Actiondescriptor:icustomattributeprovider, iuniquelyidentifiable
7: {
8: //other Members
9: Public virtual ienumerable<filterattribute> getfilterattributes (bool usecache);
10:}
The filter for the FilterAttribute feature is provided through the Filterattributefilterprovider object. Filterattributefilterprovider directly invokes the current Controllerdescriptor and Actiondescriptor getfilterattributes methods to get all applications in controller type and current Actio The FilterAttribute attribute of the N method and creates the corresponding filter object. The parameter cacheattributeinstances of the Filterattributefilterprovider constructor indicates whether the cache for FilterAttribute is enabled. It will be used as an argument to invoke the Getfilterattributes method. The default (Filterattributefilterprovider created by calling the default parameterless constructor) takes the cache for FilterAttribute.
1:public class Filterattributefilterprovider:ifilterprovider
2: {
3: Public filterattributefilterprovider ();
4: Public Filterattributefilterprovider (bool cacheattributeinstances);
5: protected Virtual ienumerable<filterattribute> getactionattributes (controllercontext ControllerContext, Actiondescriptor actiondescriptor);
6: protected Virtual ienumerable<filterattribute> getcontrollerattributes (controllercontext ControllerContext, Actiondescriptor actiondescriptor);
7: Public virtual ienumerable<filter> getfilters (ControllerContext controllercontext, Actiondescriptor Actiondescriptor);
8:}
For filter obtained by calling Getfilters, the corresponding FilterAttribute attribute is used as its instance property. The Order property originates from the FilterAttribute property of the same name. The scope property depends on whether the FilterAttribute attribute is applied on the controller type (the Scope property value is controller) or on the current action method (the scope property value is action).