ASP. NET MVC Filters 4 default filters using "attached example"

Source: Internet
Author: User
Tags httpcontext

The advent of the filter (Filters) allows us to better control the URL requested by the browser in the ASP. Not every request responds to the content, only the specific content to those who have specific permissions, the filter theoretically has the following functions:

    1. Determine login or user rights
    2. Decision output Cache
    3. Anti-theft chain
    4. Anti-Spider
    5. Localization and internationalization settings
    6. Implement dynamic action (good for a Rights management system)

Let's start with a simple example: Create a new authfilterscontroller with two action

Public ActionResult Index () {    return View ();} [Authorize]public actionresult Welcome () {    return View ();}

Obviously, the first action named Index is not filtered, any identity requests can be passed, as long as in the browser's URL bar type: Localhost:****/authfilters/index can get the corresponding view response;
The second action, named Welcome, says [authorize], which indicates that this is a URL request that only handles those authenticated URLs, and if the request is not authenticated, the action is taken to the login page. Look at the configuration file:

<authentication mode= "Forms" >  <forms loginurl= "~/account/logon" timeout= "2880"/></ Authentication>

Based on the definition of the profile, the login page is the AccountController named logon action, then create a new AccountController and create a new two action:

Public ActionResult LogOn () {    return View ();} [Httppost]public actionresult LogOn (Logonviewmodel model) {    if (model. Username.trim () = = model. Password.trim ())//pseudo-code, as long as the user name and password entered the same as the    {        if (model. RememberMe)            Formsauthentication.setauthcookie (model. UserName, true);   2,880-minute expiration cookie        else            Formsauthentication.setauthcookie (model. UserName, false);  Session Cookie        return redirecttoaction ("Welcome", "authfilters");    }    else        return View (model);}

The first is to process the GET request for the Response view page, and the second is to process the login form that the user clicked to submit the postback.

Logonviewmodel is the user login entity class, see the specific definition:

<summary>///User Login class//</summary>public class logonviewmodel{//<summary>//    user name    </summary> public    string UserName {get; set;}    <summary>//password////    </summary> public    string Password {get; set;}    <summary>////Remember me///    </summary> public    bool RememberMe {get; set;}}

OK, press F6 to compile the project, and then press CTRL + F5 to run the project, enter in the URL: Localhost:****/authfilters/index very easy to get the response of Index this action

Reposition to: Localhost:****/authfilters/welcome

It can be seen that although the action is positioned to welcome, it is not returned directly to the corresponding view as index, but is taken to the login page. This is because welcome has been labeled [authorize] on this action and has refused to authenticate the user's access.

Since the unauthenticated user has been rejected, then login to verify, see the above logon pseudo-code to know, enter the same user name and password can log on successfully, the user name and password are entered "Wangjie" try:

It has been validated and received a response from the welcome action. Compared to the previous one is more generated a named ". Aspxauth "Cookie, which is a default name, can be modified in the configuration file. Also, if you check "Remember Me" when you log in, the expiration time of this cookie is 2,880 minutes defined in the configuration file.

OK, now improve the difficulty, only set the name "a", "BB", "CCC" users can visit the Welcome page:

[Authorize (Users = "A,BB,CCC")]public ActionResult Welcome () {    viewbag.message = "logged in";    return View ();}

Again with "Wangjie" login to find the Welcome page, because the designated a, BB, CCC three users can log in.
First, regardless of why the user = "A,BB,CCC" On the action can control which users can access, it is convenient to control the access rights of the action from an operational standpoint. However, if the project is large, the user's corresponding roles and permissions change relatively large, each change to re-labeling action is obviously inappropriate. The filter provided by the MVC Framework (Filters) comes in handy:

There are several default filter: Authorization filters, action filters, result filters, exception filters provided by the ASP. One by one, let's take a look at the demo demo chart:

One, Authorization filter

Authorization filters are used to implement the Iauthorizationfilter interface and make security decisions about whether to perform an action method, such as a property that performs an authentication or validation request. The Authorizeattribute class and the Requirehttpsattribute class are examples of authorization filters. The authorization filter runs before any other filters.
To create a new Userauthorize class that inherits the Authorizeattribute class, F12 navigates to the Authorizeattribute class and looks at the internal declaration:

Public Authorizeattribute ();p ublic string Roles {get; set;} Public override object TypeId {get;} public string Users {get; set;} Protected virtual bool Authorizecore (httpcontextbase HttpContext);p rotected virtual void handleunauthorizedrequest ( AuthorizationContext filtercontext);p ublic virtual void onauthorization (AuthorizationContext filtercontext); Protected virtual HttpValidationStatus oncacheauthorization (HttpContextBase HttpContext);

The specified user that is shown above is accessible only by taking advantage of the users property and by the base class to help us verify that only the specified users user is passed. To implement custom validation simply rewrite the next onauthorization and Authorizecore methods. To demonstrate the effect, create a new Sampledata class to initialize the data:

<summary>///test data (the data should be taken from the database in the actual project)///</summary>public class sampledata{public static list<user& Gt    Users    public static list<role> roles;    public static list<rolewithcontrolleraction> rolewithcontrollerandaction; Static SampleData () {//Initialize user users = new list<user> () {new user () {id=1, username= "wan Gjie ", roleid=1}, new User () {id=2, UserName =" Senior1 ", roleid=2}, new User () {id=3, UserName =" Sen Ior2 ", roleid=2}, new User () {id=5, username=" Junior1 ", roleid=3}, new User () {id=6, username=" Junio        R2 ", roleid=3}, New User () {id=6, username=" Junior3 ", roleid=3}}; Initialize role roles = new list<role> () {new role () {id=1, rolename= "admin", description= "Administrator Role"} , new Role () {id=2, rolename= "Advanced member", description= "Advanced member Role"}, new Role () {id=3, rolename= "Junior member", Des        Cription= "Junior member role"}; //Initialize the role controller and action corresponding class rolewithcontrollerandaction = new List<rolewithcontrolleraction> () {New Rolewithcontrolleraction () {id=1, controllername= "Authfilters", actionname= "AdminUser", roleids= "1"}, new Role Withcontrolleraction () {id=2, controllername= "Authfilters", actionname= "Senioruser", ids= "Up"}, new RoleWithCo Ntrolleraction () {id=3, controllername= "Authfilters", actionname= "Junioruser", ids= "by"}, new Rolewithcontro    Lleraction () {id=4, controllername= "Actionfilters", actionname= "Index", roleids= "2,3"}}; }}

Simple and straightforward, the user has a role, and different roles can access different action. This is more in line with the control in the permission item. Then look at the specific definition of the Userauthorize class:

<summary>///Custom user Authorization//</summary>public class userauthorize:authorizeattribute{//<summary>    View rendered when authorization fails//</summary> public string Authorizationfailview {get; set;} <summary>////</summary> public override void Onauthorization (AuthorizationContext FI) when requesting authorization Ltercontext) {//Get controller and action:string in URL request controllername = filtercontext.routedata.values["cont Roller "]. ToString ().        ToLower (); String actionname = filtercontext.routedata.values["Action"]. ToString ().        ToLower ();        string controllername = FilterContext.ActionDescriptor.ControllerDescriptor.ControllerName;        string actionname = FilterContext.ActionDescriptor.ActionName; According to the Controller and action requested to query which roles can be manipulated: models.rolewithcontrolleraction rolewithcontrolleraction = base. SampleData.roleWithControllerAndAction.Find (r = r.controllername.tolower () = = Controllername && Tionname.tolower() = = ActionName); if (rolewithcontrolleraction! = null) {this.     Roles = Rolewithcontrolleraction.roleids; has permission to manipulate the role ID} base of the current Controller and action.   Onauthorization (Filtercontext); Enter Authorizecore}///<summary>///Custom authorization check (return FALSE for authorization failure)///</summary> protected override B            Ool Authorizecore (HttpContextBase HttpContext) {if (httpContext.User.Identity.IsAuthenticated) {    string userName = HttpContext.User.Identity.Name;   Username Models.user user = Database.SampleData.users.Find (U = u.username = = UserName); The currently logged on user object if (user! = null) {Models.role Role = Database.SampleData.roles.Find (R =& Gt R.id = = user.  Roleid); The role of the currently logged on user is foreach (String Roleid in Roles.split (', ')) {if (role.                id.tostring () = = Roleid) return true;    } return false;        } else return false;     } else return false; Enter Handleunauthorizedrequest}///<summary>//To handle HTTP requests for failed authorization///</summary> protected Overr  IDE void Handleunauthorizedrequest (AuthorizationContext filtercontext) {Filtercontext.result = new ViewResult {    ViewName = Authorizationfailview}; }}

Custom authorization classes can be used on the controller to see the Authfilterscontroller class:

public class authfilterscontroller:controller{Public    actionresult Index ()    {        return View ();    [Authorize (Users = "A,BB,CCC")]    [authorize] public    ActionResult Welcome ()    {        viewbag.message = " Normal Authorized page ";        return View ();    }    [Userauthorize (Authorizationfailview = "Error")]   Admin page Public    actionresult AdminUser ()    {        viewbag.message = "Admin page";        Return View ("Welcome");    }    [Userauthorize (Authorizationfailview = "Error")]   Member page (administrators, members can access) public    ActionResult Senioruser ()    {        Viewbag.message = "Premium Member page";        Return View ("Welcome");    }    [Userauthorize (Authorizationfailview = "Error")]   Visitors page (administrators, members, visitors are accessible) public    ActionResult Junioruser ()    {        viewbag.message = "Junior member page";        Return View ("Welcome");}    }

Welcome this action uses the default authorization authentication, which can be accessed only if the login is successful. Several other actions are marked with custom userauthorize, and there is no label users= "....", roles= "...", because it is obviously not feasible to write dead user or role control permissions on the action. The actions that the user and role correspond to and the different roles can manipulate should be taken out of the database. In order to demonstrate the initialization of some user and role information in the Sampledata class, according to the definition of the Sampledata class, it is obvious that Wangjie has the 1th Administrator role and can access all Action,senior1 under Authfilters this controller, Senior2 has the role of 2nd senior member, can access authfilters under this controller except Adminuser action and so on
Once again, it is found that the user with the Advanced membership role, SENIOR1, is not allowed to access the Adminuser action, which is taken to the error view specified by the Authorizationfailview property:

Second, action filter, result filter

Action filters are used to implement the Iactionfilter interface and the wrapper action method execution. The Iactionfilter interface declares two methods: OnActionExecuting and onactionexecuted. OnActionExecuting run before the action method. OnActionExecuted run after the action method, you can perform additional processing, such as providing additional data to the action method, checking the return value, or canceling the action method.

The result filter is used to implement the Iresultfilter interface and the execution of the wrapper ActionResult object. The Iresultfilter interface declares two methods onresultexecuting and onresultexecuted. Onresultexecuting runs before executing the ActionResult object. Onresultexecuted runs after the result and can perform additional processing on the result, such as modifying the HTTP response. The Outputcacheattribute class is an example of a result filter.

Both the action filter and the result filter implement the ActionFilterAttribute class to see the methods defined in the class:

public virtual void onactionexecuted (ActionExecutedContext filtercontext);p ublic virtual void onactionexecuting ( ActionExecutingContext filtercontext);p ublic virtual void onresultexecuted (ResultExecutedContext filterContext); public virtual void onresultexecuting (ResultExecutingContext filtercontext);

According to the name of the method, you know the order in which 4 methods are executed:
OnActionExecuting is the action before action executes, onactionexecuted is the action after action, Onresultexecuting is the parse actionresult before execution, Onresultexecuted is performed after parsing ActionResult
That is: Before the action executes: The OnActionExecuting method executes the →action execution →onactionexecuted method execution →onresultexecuting Method execution → Returns the Actionrsult in the Executeresult method Execution →onresultexecuted execution

You can completely override the OnActionExecuting method to implement the same functionality as the authorization filter above, because the OnActionExecuting method is run before the action method executes. To customize a Actionfilters class that implements the ActionFilterAttribute class, the OnActionExecuting method writes:

<summary>///called by the MVC framework before executing the action method//</summary>public override void OnActionExecuting (    ActionExecutingContext filtercontext) {string userName = FilterContext.HttpContext.User.Identity.Name;   Username Models.user user = Database.SampleData.users.Find (U = u.username = = UserName); The currently logged on user object if (user! = null) {Models.role Role = Database.SampleData.roles.Find (r = = R.id = = user.  Roleid); The role of the currently logged on user//get controller:string Controllername = filtercontext.routedata.values["Controller"]. ToString ().        ToLower (); String actionname = filtercontext.routedata.values["Action"]. ToString ().        ToLower (); if (ActionName = = null) ActionName = filtercontext.routedata.values["Action"].        ToString (); Query role ID models.rolewithcontrolleraction rolewithcontrolleraction =. SampleData.roleWithControllerAndAction.Find (r = r.controllername.tolower () = = Controllername && Name.tolower () = = Actionname.tolower ());        if (rolewithcontrolleraction! = null) {this.     Roles = Rolewithcontrolleraction.roleids; has permission to manipulate the current controller and action's role ID} if (!string. IsNullOrEmpty (Roles)) {foreach (String Roleid in Roles.split (', ')) {if (role .   id.tostring () = = Roleid) return;   Return is a description of the permissions, the following code will not run, directly return to the view of the browser is good}} Filtercontext.result = new Emptyresult (); Request failed output null result HttpContext.Current.Response.Write ("Sorry, you don't have permission!")   ");    typing hint text//return;        } else {//filtercontext.result = new ViewResult {ViewName = "Error"};        Filtercontext.result = new Emptyresult (); HttpContext.Current.Response.Write ("Sorry, please login first!")        ");    Return }//base. OnActionExecuting (Filtercontext);}

See how to make it in the Actionfilterscontroller controller:

public class actionfilterscontroller:controller{    [actionfilters] public    actionresult Index ()    {        return View ();    }    [Actionfilters (ActionName = "Index")]    Public ActionResult Details ()    {        return View ();    }    [Actionfilters]    Public ActionResult Test ()    {        return View ();    }}

It is clear that the index and details of the two action with a permission to see the initialization of the data Sampledata class definition:

New Rolewithcontrolleraction () {id=4, controllername= "Actionfilters", actionname= "Index", roleids= "2,3"}

Only the 2 and 3rd roles can be accessed, then the Wangjie user of role 1th should not be able to access, login try:

Third, exception filter

The exception filter is used to implement the Iexceptionfilter interface and is executed when an unhandled exception is thrown during the ASP. NET MVC pipeline execution. Exception filters can be used to perform tasks such as logging or displaying error pages. The Handleerrorattribute class is an example of an exception filter.

With experience with previous authorization filters, operations, and result filters, it's a lot easier to look at the exception filters, to see the custom inherited exception filter class Exceptionfilters from the Handleerrorattribute class:

<summary>///exception Filter//</summary>public class exceptionfilters:handleerrorattribute{//&LT;SUMMARY&G    T Call///</summary> public override void Onexception (Exceptioncontext filtercontext) {//if When an exception occurs) (!filtercontext.exceptionhandled && filtercontext.exception is NullReferenceException) if (!filterContext.E xceptionhandled) {//Gets the controller name and action name of the exception that is used to log string controllername = (string) Filterco ntext.            routedata.values["Controller"];            String actionname = (string) filtercontext.routedata.values["action"; Define a handerrorinfo for the error view to display exception information Handleerrorinfo model = new Handleerrorinfo (filtercontext.exception, contro            Llername, ActionName); ViewResult result = new ViewResult {ViewName = this.            View, ViewData = new viewdatadictionary

See how to use it in the view:

[Exceptionfilters (View = "Exception")]public ActionResult Index () {    throw new NullReferenceException ("Test throws an exception!) ");}

View is the set of views that are displayed to the user after catching an exception:

Look at one more action:

[Exceptionfilters (View = "Exceptiondetails")]public ActionResult Details () {    int i = Int. Parse ("hello,world!");    return View ();}

To strongly transfer string data to int, it is certain to report FormatException exceptions to see how the Exceptiondetails view is defined:

@model system.web.mvc.handleerrorinfo@{    Layout = null;} <! DOCTYPE html>

The browser displays the results:

Thank you for reading, if you feel good, please give me a "praise", thank you.

This article source

ASP. NET MVC Filters 4 default filters using "attached example"

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.