MVC source code analysis, mvc source code
As shown in the previous article, there are four filters for program execution:
Filter Type |
Interface |
Description |
Authorization |
IAuthorizationFilter |
This type (or filter) is used to restrict a behavior method to the Controller or controller. |
Exception |
IExceptionFilter |
Specifies an action. This action is used to process an action method or an exception thrown in a controller. |
Action |
IActionFilter |
Used for processing before or after a behavior |
Result |
IResultFilter |
Used for processing before or after the returned results |
However, there are only three filters implemented by default, namely Authorize (authorization), ActionFilter, and HandleError (error handling). The following table lists the information.
Filter |
Class Name |
Implementation Interface |
Description |
ActionFilter |
AuthorizeAttribute |
IAuthorizationFilter |
This type (or filter) is used to restrict a behavior method to the Controller or controller. |
HandleError |
HandleErrorAttribute |
IExceptionFilter |
Specifies an action. This action is used to process an action method or an exception thrown in a controller. |
Custom |
ActionFilterAttribute |
IActionFilter and IResultFilter |
Used for processing before or after a behavior or before or after a returned result |
The following describes these filters.
1. Authorization filter Authorize
1. Method 1: OnAuthorization method in the Controller class
The newly created Controller class directly or indirectly inherits from the Controller class. In the Controller, there is an OnAuthorization method, which is also in the authorization filter.
// Abstract: // defines the methods required for the authorization filter. Public interface IAuthorizationFilter {// Abstract: // called when authorization is required. //// Parameter: // filterContext: // filter context. Void OnAuthorization (AuthorizationContext filterContext );}
In this way, you do not need to configure your own filter in the FilterConfig file.
I will first create a feature. As long as the method is added with this feature, login verification is not required.
public class AllowLoginAttribute : Attribute{}
There is no content in it, and no content is required.
Then there is the filter method.
Public class HomeController: Controller {protected override void OnAuthorization (AuthorizationContext filterContext) {var attrs = filterContext. actionDescriptor. getCustomAttributes (typeof (AllowLoginAttribute), true); if (attrs. count ()> 0) {return;} var cookie = Request. cookies ["Login"]; if (cookie = null | cookie. value! = "Already Login "){
// As previously parsed, you only need to assign a value to the Result to influence the process filterContext. Result = RedirectToAction ("Login ");}}
// This method will give the browser a Cookie to identify whether the user has logged on.
// In actual use, a logon page can be created, requiring logon, and then sending Cookie and Session [AllowLogin] public ActionResult Login () {HttpCookie cookie = new HttpCookie ("Login ", "Already Login"); cookie. expires = DateTime. now. addMinutes (3); Response. cookies. add (cookie); return View ();}
// Here is the public ActionResult Index () {return View ();}}
Next, I will go directly to the Index page to see:
Directly jump to the login page. At this time, the browser has obtained the desired Cookie. At this time, visit the Index page.
Access successful.
Because this method is written in the controller, it is only valid for the method in the Controller. That is to say, if I access another controller at this time, this method will not work.
So should I write it in each controller? Or can I create a controller parent class for other classes to inherit the class I wrote? Is it a little too troublesome.
Is it swollen? The method is as follows:
2. Method 2: OnAuthorization method of AuthorizeAttribute
The content in the method is the same as above, but the storage location of this method is different.
But there are several differences.
2.1 register your own filter in FilterConfig
public class FilterConfig{ public static void RegisterGlobalFilters(GlobalFilterCollection filters) { filters.Add(new MyAuthAttribute()); filters.Add(new HandleErrorAttribute()); }}
2.2 jump, slightly different
public class MyAuthAttribute : AuthorizeAttribute{public override void OnAuthorization(AuthorizationContext filterContext) { var attrs = filterContext.ActionDescriptor.GetCustomAttributes(typeof(AllowLoginAttribute), true); if (attrs.Count() > 0) { return; } var cookie = HttpContext.Current.Request.Cookies["Login"]; if (cookie == null || cookie.Value != "Already Login") { filterContext.Result = new RedirectToRouteResult(
new RouteValueDictionary(new { controller = "Home", action = "Login" })); return; } }}
2.3 it is best to modify the configuration in the Web. config file.
<system.web> <authentication mode="Forms"> <forms loginUrl="~/Home/Login" timeout="2880" /> </authentication></system.web>
I tested it myself, and it is OK. The result will not be posted, and nothing else can be seen. It is the same as above.
3. Method 3: AuthorizeAttribute's AuthorizeCore Method
This method is simple. If false is returned, the jump will be performed based on the configuration file above. Generally, the OnAuthorization and AuthorizeCore methods here will be used together.
Let's take a look at the Code:
Public class MyAuthAttribute: AuthorizeAttribute {
// In this method, I determine whether the User has logged on to protected override bool AuthorizeCore (HttpContextBase httpContext) {bool isAuth = httpContext. User. Identity. IsAuthenticated; return isAuth ;}
// In this method, I determine whether the Action needs to log on to public override void OnAuthorization (AuthorizationContext filterContext) {var attrs = filterContext. actionDescriptor. getCustomAttributes (typeof (AllowLoginAttribute), true); if (attrs. count ()> 0) {return;} base. onAuthorization (filterContext );}}
Modify the Login method in the HomeController.
[AllowLogin] public ActionResult Login (){
// After this method is executed, true FormsAuthentication. SetAuthCookie ("Login", false); return View ();} can be obtained from Identity ();}
Directory synchronized