.Net Mvc 四种过滤器

一.授权过滤器:AuthorizationFilters 

二.动作过滤:ActionFilters

三.响应过滤:ResultFilters

四.异常过滤:ExceptionFilters

========================================================================================================================

一。授权过滤,这里以登陆账号密码,角色id不同进行过滤。

1.添加一个过滤类 , 用于过滤掉和角色id不符合要求的账号。

 1 using Newtonsoft.Json;
 2 using Solution.Models;
 3 using System;
 4 using System.Collections.Generic;
 5 using System.Linq;
 6 using System.Web;
 7 using System.Web.Mvc;
 8 using System.Web.Security;
 9 
10 namespace Solution.Filter
11 {
12     public class UserAuthorize : AuthorizeAttribute
13     {
14         //允许的角色id集合
15         public string[] x { get; set; }
16 
17         /// <summary>
18         /// 请求授权时调用相关的参数
19         /// </summary>
20         /// <param name="filterContext"></param>
21         public override void OnAuthorization(AuthorizationContext filterContext)
22         {
23             string[] str = Roles.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries);
24             x = new string[str.Length];
25             for (int i = 0; i < str.Length; i++)
26             {
27                 x[i] = str[i];
28             }
29             base.OnAuthorization(filterContext);
30         }
31 
32         protected override bool AuthorizeCore(HttpContextBase httpContext)
33         {
34             var thisUser = UserHelper.user;
35             bool status = true;
36             //判断是否登陆
37             if (!HttpContext.Current.User.Identity.IsAuthenticated)
38             {
39                 return false;
40             }
41 
42             //判断角色
43             if (x.Count() > 0 && status==true)
44             {
45                 status = x.Contains(thisUser.role);
46             }
47 
48             return status; 
49          
50         }
51     }
52 
53 
54  
55 
56 }
View Code

2.在Home控制器下添加对应的登陆和退出方法,登陆后跳转的页面。

创建LogDto类,用于封装登陆时需填写的属性

 1 using System;
 2 using System.Collections.Generic;
 3 using System.Linq;
 4 using System.Text;
 5 using System.Threading.Tasks;
 6 
 7 namespace Solution.Model
 8 {
 9    public class LogDto
10     {
11        public string Account { get; set; }
12 
13        public string PassWord { get; set; }
14     }
15 }
View Code

创建UserIdEntity类,用于封装存入cookie的票据信息

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;

namespace Solution.Models
{
    public class UserIdEntity
    {
        public string Account { get; set; }

        public string PassWord { get; set; }

        public string role { get; set; }
    }
}
View Code

创建ResponseMsg类,用于方法返回的结果信息

 1 using System;
 2 using System.Collections.Generic;
 3 using System.Linq;
 4 using System.Text;
 5 using System.Threading.Tasks;
 6 
 7 namespace Solution.Common
 8 {
 9     public class ResponseMsg
10     {
11         /// <summary>
12         /// 默认构造函数
13         /// </summary>
14         public ResponseMsg()
15         {
16         }
17 
18         /// <summary>
19         /// 设置初始值
20         /// </summary>
21         /// <param name="_Status"></param>
22         public ResponseMsg(ActonState _Status)
23         {
24             _status = _Status;
25         }
26 
27         public ActonState _status;
28 
29         public ActonState Status
30         {
31             get { return _status; }
32             set { _status = value; }
33         }
34 
35 
36         public string Msg { get; set; }
37 
38         public string LoadUrl { get; set; }
39 
40         public object Data { get; set; }
41 
42     }
43 
44     public enum ActonState
45     {
46         Default = 0,//默认
47 
48         Success = 1, //成功
49 
50         Failure = 2,//失败
51 
52         ServerError = 3,//服务错误
53 
54         Others = 4 //其它
55     }
56 }
View Code

在Home控制器下编写登陆方法

[HttpPost]//只允许post请求
        public ActionResult LogOn(LogDto logdto)
        {
            string name = logdto.Account;
            string pwd = logdto.PassWord;
            ResponseMsg response = new ResponseMsg() { Status = ActonState.Default };


            if ("Admin".Equals(name) && "123456".Equals(pwd))
            {
                UserIdEntity identity = new UserIdEntity() { Account = name, PassWord = pwd, role = "1" };
                //创建Form票据
                FormsAuthenticationTicket ticket = new FormsAuthenticationTicket(1, name, DateTime.Now, DateTime.Now.AddHours(1), false, JsonConvert.SerializeObject(identity));
                //将票证转为字符串(加密)
                string str = FormsAuthentication.Encrypt(ticket);
                //将该票证存到cookie中
                //FormsAuthentication.SetAuthCookie(str,true);
                HttpCookie coo = new HttpCookie("DIQx", str); //cookie名称必须与配置中名称相同,否则读取不到userdata
                Response.Cookies.Add(coo);
                response.LoadUrl = "/Home/Main";
                response.Status = ActonState.Success;
            }
            else {
                response.Status = ActonState.Default;
            }
            return Json(response);
        }
View Code

要跳转的页面,这里只允许角色Id为(1,2,3)中的其中的一个进入。且[Roles=""]标记为固定写法

1   [UserAuthorize(Roles="1,2,3")]
2         public ActionResult Main()
3         {
4             return View();
5         }
View Code

退出登陆

  [AllowAnonymous] //允许匿名
        public ActionResult OutLogon() 
        {
            Session.Abandon();
            FormsAuthentication.SignOut();
            return RedirectToAction("Index","Home");
        }
View Code

在Web.config文件里  <system.web> 下添加配置如下, 

<authentication mode="Forms">
<forms loginUrl="~/Home/Index" name="DIQx" timeout="2880" />
</authentication>

注:name="DIQx" 这个name值和登陆时把票据存入cookie时的cookie名称相同。

 

测试一下。

①什么也不填,直接地址栏输入要跳转的页面

②账号或密码输入错误的。

③角色id不是(1,2,3)中的一个

以上三种情况都会被阻止,并且跳转至刚才在WebConfig中配置的url地址

满足正确条件,返回Main页面 

二。动作过滤  这里编写一个WebApi,对api方法进行加密。

编写过滤类,重写OnActionExecuting方法

 1 using System;
 2 using System.Collections.Generic;
 3 using System.Linq;
 4 using System.Web;
 5 
 6 
 7 using System.Net.Http;
 8 using Solution.Common;
 9 using System.Web.Http.Controllers;
10 using System.Web.Http.Filters;
11 namespace Solution.Filter
12 {
13     public class SecreKeyAttribute : ActionFilterAttribute
14     {
15 
16         public override void OnActionExecuting(System.Web.Http.Controllers.HttpActionContext actionContext)
17         {
18 
19             ResponseMsg response = new ResponseMsg() { Status = ActonState.Default };
20 
21             //var Ticket = actionContext.ActionArguments["Ticket"];//get请求时带的参数
22 
23             var Ticket = System.Web.HttpContext.Current.Request["Ticket"];
24 
25             if (Ticket == null)
26             {
27                 response.Msg = "请传入密钥!";
28                 actionContext.Response = actionContext.Request.CreateResponse(System.Net.HttpStatusCode.OK, response);
29             }
30             else
31             {
32                 string SecrtetKey = Ticket.ToString();
33                 if (!SecrtetKey.Equals("88888888"))
34                 {
35                     response.Msg = "密钥错误!";
36                     actionContext.Response = actionContext.Request.CreateResponse(System.Net.HttpStatusCode.OK, response);
37                 }
38             }
39             base.OnActionExecuting(actionContext);
40 
41         }
42 
43 
44         public override void OnActionExecuted(HttpActionExecutedContext actionExecutedContext)
45         {
46 
47             base.OnActionExecuted(actionExecutedContext);
48         }
49 
50     }
51 }
View Code

编写WebApiConfig配置文件,

 1 using System;
 2 using System.Collections.Generic;
 3 using System.Linq;
 4 using System.Web;
 5 using System.Web.Http;
 6 
 7 namespace Solution.Models
 8 {
 9     public class WebApiConfig
10     {
11         public static void Register(HttpConfiguration config)
12         {
13             //config.MapHttpAttributeRoutes();
14 
15             config.Routes.MapHttpRoute(
16                 name: "DefaultApi",//默认请求api地址
17                 routeTemplate: "api/{controller}/{action}/{id}", //例如: 
18 http://localhost:41464/api/ScreateKey/GetInfo
19                 defaults: new { id = RouteParameter.Optional });
20         }
21     }
22 }
View Code

在Golba.asax中Application_Start()方法下加入刚才的WebApi文件配置

 WebApiConfig.Register(GlobalConfiguration.Configuration);

创建对应的api方法,并加入 [SecreKey]标签

 1 using Solution.Common;
 2 using System;
 3 using System.Collections.Generic;
 4 using System.Linq;
 5 using System.Web;
 6 using System.Web.Http;
 7 
 8 using System.Net;
 9 using System.Net.Http;
10 using Solution.Filter;
11 
12 
13 namespace Solution.Controllers
14 {
15     public class ScreateKeyController : ApiController
16     {
17 
18 
19         // GET: ScreateKey
20         [SecreKey]
21         [HttpPost]
22         public ResponseMsg GetInfo([FromBody]string Ticket)
23         {
24             ResponseMsg response = new ResponseMsg() { Status = ActonState.Default };
25             response.Msg = "密钥正确时,会返回这个结果";
26             return response;
27         }
28     }
29 }
View Code

注:这里用的是post请求。 参数必须带上这个[FromBody],不然请求不到。而且这个[FromBody]只能用一次,如果有多个参数就只能封装到一个类里面。

 

测试一下。正确密钥 “8888888”

密钥错误:

 

密钥正确:

三。结果过滤

 添加一个过滤特性类

 1 using Solution.Common;
 2 using System;
 3 using System.Collections.Generic;
 4 using System.Linq;
 5 using System.Web;
 6 using System.Web.Mvc;
 7 
 8 namespace Solution.Filter
 9 {
10     public class ResultAttribute : ActionFilterAttribute
11     {
12         public override void OnResultExecuting(ResultExecutingContext resultContext)
13         {
14             ResponseMsg response = new ResponseMsg() { Status = ActonState.Default };
15             resultContext.HttpContext.Response.Write("<br/> 结果返回之前执行");
16             base.OnResultExecuting(resultContext);
17         }
18 
19         public override void OnResultExecuted(ResultExecutedContext resultContext) 
20         {
21             ResponseMsg response = new ResponseMsg() { Status = ActonState.Default };
22             resultContext.HttpContext.Response.Write("<br/> 结果返回之后执行");
23             base.OnResultExecuted(resultContext);
24         }
25     }
26 }
View Code

在Home控制器添加一个视图,并添加[Result]标签

1 [Result]
2         public ActionResult FunResult() 
3         {
4             return View();
5         }
View Code

在FunResult.cshtml页面加入如下代码:

@{
Response.Write("<br/> 返回的结果");
}

 

测试一下,得到结果如下图:

 

四。异常过滤

创建一个发生错误时跳转的页面

添加一个异常过滤特性类

 1 using System;
 2 using System.Collections.Generic;
 3 using System.Linq;
 4 using System.Web;
 5 
 6 using System.Web.Mvc;
 7 
 8 namespace Solution.Filter
 9 {
10     //异常过滤器
11     public class HandErrorAttribute :HandleErrorAttribute
12     {
13         //程序中任何一个地方发生异常都会处理
14         public override void OnException(ExceptionContext filterContext) 
15         {
16             //获取异常对象
17             Exception ex = filterContext.Exception;
18             
19             //记录日志
20 
21             //发生错误后,跳转的页面
22             filterContext.Result = new RedirectResult("/Home/Error");
23 
24             //告知异常已被处理。如果没有则按照系统正常的异常处理流程走!
25             filterContext.ExceptionHandled = true;
26 
27         }
28     }
29 }
View Code

在App_Start文件夹下创建FilterConfig文件

 1 using Solution.Filter;
 2 using System.Web;
 3 using System.Web.Mvc;
 4 
 5 namespace Solution
 6 {
 7     public class FilterConfig
 8     {
 9         public static void RegisterGlobalFilters(GlobalFilterCollection filters)
10         {
11             filters.Add(new HandErrorAttribute());
12         }
13     }
14 }
View Code

在Glabal.asa文件Application_Start()方法下添加刚才的筛选配置

 FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);

 

转载于:https://www.cnblogs.com/-xyl/p/9269495.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值