When we visit a website, we need to detect whether the user is logged in (through the session is null), We know that in WebForm you can define a BasePage class that lets him inherit System.Web.UI.Page, rewrite its oninit () method, and in OnInit () determine if there is a user login in the session.
<summary>///public things in common base class///</summary>public class BasePage:System.Web.UI.Page {// The OnInit () method corresponding to the page life-cycle init event //This method will precede the Pageload method to execute the //override representation of overriding the OnInit method, which is raised after all controls have been initialized and all appearance settings have been applied. Use this event to read or initialize a control property protected override Voidoninit (EventArgs e) { base. OnInit (e); if (session["UserInfo"] = = NULL) //Check whether the user is logged in { //jump to the login page }}}
How do you check it under MVC?
We know that under MVC you can customize an attribute class to [attribute] on a controller or a controller, where only the Actionfilter filter is required (the action method executes before and after execution), and MVC provides the Iactionfilter interface. (For convenience we can use Microsoft to provide good ActionFilterAttribute class, he is the filter attribute of the base class, is also an abstract class, in fact, this abstract class implementation of Iactionfilter and Iresultfilter)
Definition of the Iactionfilter interface:
Called after the action method is executed.
void onactionexecuted (ActionExecutedContext filtercontext);
Called before the action method is executed.
void OnActionExecuting (ActionExecutingContext filtercontext);
Create a new attribute class Logincheckfilterattribute, let him inherit the ActionFilterAttribute, and rewrite the OnActionExecuting method in which to complete the checksum
public class Logincheckfilterattribute:actionfilterattribute {}
Indicates whether to check logon public bool Ischeck {get; set;}
//action method before executing this method Public overridevoid onactionexecuting (ActionExecutingContext filtercontext) {base. OnActionExecuting (Filtercontext); if (Ischeck) {//verifies whether the user is already logged on if (filtercontext.ht tpcontext.session["Loginuser"] ==null) {//Jump to landing page FilterContext.HttpContext.Response.Redirect ("/userlogin/index"); }} else{//Jump to Homepage FilterContext.HttpContext.Response.Redirect ("/home/index"); }}<span style= "FONT-SIZE:14PX;" > How to make this filter work? </span>
Steps:
1. Register the global filter for the MVC program in the Global.asax file and call Filterconfig.registerglobalfilters (Globalfilters.filters).
The Filterconfig class is in the App_start folder (creating a new MVC project is automatically generated).
In static method of Filterconfig public static void Registerglobalfilters (Globalfiltercollection filters) Registers global filter public class Filterconfig { //This method is used to register a global filter (called in global) public static Voidregisterglobalfilters ( Globalfiltercollection filters) { //filters. ADD (Newhandleerrorattribute ()); Filters. ADD (Newlogincheckfilterattribute () {Ischeck = true}); } }
Note To assign a value of true to the Ischeck property of an attribute class instance, the session check does not work.
In this way, the Logincheckfilterattribute feature will work for the Controller and action in the entire MVC program, meaning that the override onactionexecuting method in the attribute class is called before the action method is executed. This allows users to visit the site will first detect whether the user is logged in, if not logged in will jump to the login page.
But! But! The problem is, because we are registering a global filter , this filter feature will work on all the actions of the controller, when visiting the website (for example, we register the default route to/home/index) will first jump to/home/index, The Index method is not executed at this point, the check in OnActionExecuting () is performed first, and the session is Null,response.redirect ("/userlogin/index") to the login page; The login page is still not visible in the browser , why? Remember that we registered the global filter, the action object including all the controller under the action of course also includes/userlogin/index, the code went here will be executed again onactionexecuting () method, found session[" UserInfo "==]null, jumped to the login page, we can't even see the login page can not enter the user name password session will not have login information, the browser will return" This page contains redirect Loop "error page, that is, will continue to redirect to the login page, Like a dead loop, the browser certainly strikes.
How to solve this bug?
I tried two workarounds:
Method 1: Make the Userlogincontroller controller feature
[Logincheckfilterattribute (ischeck= false)]//Hit the user login check attribute (Ischeck set to False does not make it work on this controller , but on other controllers and action, Prevent redirect loop) public class Userlogincontroller:controller {...}
When defining this attribute class, we have a bool attribute Ischeck, which indicates whether the checksum is set to false to indicate no checksum. By the way, Logincheckfilterattribute can omit the attrbute suffix.
Be sure to hit this feature on the controller , not just for one of the actions below, because there is an action to generate the CAPTCHA and the action to process the login request, they do not need a session check (meaningless), Hitting the feature on the controller will work on all the actions underneath it, without hitting the feature for each action, saving the amount of code. We have registered a global filter and individually filter the Userlogincontroller controller, there is a priority problem action>controller> the global, Userlogincontroller are not affected by global filters.
To test here, enter the website address, successfully enter the login page, enter the correct user name password click Login, the browser returned
Error message, debugging a bit or the previous problem, but can display the login page, login session["UserInfo" after the user, will still be infinitely redirected, because it will be executed before the action in OnActionExecuting (), At this time even if sessio["UserInfo"]!=null, it will also cause a dead loop, solution:
The execution of the report exception, this time to add in Global.asax: Open session function public class WebApiApplication:System.Web.HttpApplication {public override void Init () {this . Postauthenticaterequest + = (sender, E) = HttpContext.Current.SetSessionStateBehavior ( sessionstatebehavior.required); Base. Init (); } }
Method 2: Take advantage of the Basecontroller class (similar to Webfrom's BasePage)
1. Create a new Basecontroller class, inherit System.Web.Mvc.Controller, define a UserInfo attribute in the class, save the user entity from session["UserInfo" to facilitate his derived class invocation.
2, F12 define System.Web.Mvc.Controller this kind of discovery
Public abstract class Controller:controllerbase, Iactionfilter, iauthorizationfilter,idisposable, Iexceptionfilter, Iresultfilter, Iasynccontroller, Icontroller,iasyncmanagercontainer {//...}
It also realizes the Iactionfilter interface, it does not need the above our global filter , only needs to rewrite the onactionexecuting () method, the logic and the filter code, so that the need for login verification of the controller to inherit the Basecontroller class can be, equivalent to the Basecontroller controller on the above check characteristics, the perfect solution to the problem of login verification.
MVC detects if a user is logged in