.Net Mvc 四种过滤器
一.授权过滤器:AuthorizationFilters
二.动作过滤:ActionFilters
三.响应过滤:ResultFilters
四.异常过滤:ExceptionFilters
========================================================================================================================
一。授权过滤,这里以登陆账号密码,角色id不同进行过滤。
1.添加一个过滤类 , 用于过滤掉和角色id不符合要求的账号。
using Newtonsoft.Json;
using Solution.Models;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using System.Web.Security; namespace Solution.Filter
{
public class UserAuthorize : AuthorizeAttribute
{
//允许的角色id集合
public string[] x { get; set; } /// <summary>
/// 请求授权时调用相关的参数
/// </summary>
/// <param name="filterContext"></param>
public override void OnAuthorization(AuthorizationContext filterContext)
{
string[] str = Roles.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries);
x = new string[str.Length];
for (int i = ; i < str.Length; i++)
{
x[i] = str[i];
}
base.OnAuthorization(filterContext);
} protected override bool AuthorizeCore(HttpContextBase httpContext)
{
var thisUser = UserHelper.user;
bool status = true;
//判断是否登陆
if (!HttpContext.Current.User.Identity.IsAuthenticated)
{
return false;
} //判断角色
if (x.Count() > && status==true)
{
status = x.Contains(thisUser.role);
} return status; }
} }
2.在Home控制器下添加对应的登陆和退出方法,登陆后跳转的页面。
创建LogDto类,用于封装登陆时需填写的属性
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks; namespace Solution.Model
{
public class LogDto
{
public string Account { get; set; } public string PassWord { get; set; }
}
}
创建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; }
}
}
创建ResponseMsg类,用于方法返回的结果信息
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks; namespace Solution.Common
{
public class ResponseMsg
{
/// <summary>
/// 默认构造函数
/// </summary>
public ResponseMsg()
{
} /// <summary>
/// 设置初始值
/// </summary>
/// <param name="_Status"></param>
public ResponseMsg(ActonState _Status)
{
_status = _Status;
} public ActonState _status; public ActonState Status
{
get { return _status; }
set { _status = value; }
} public string Msg { get; set; } public string LoadUrl { get; set; } public object Data { get; set; } } public enum ActonState
{
Default = ,//默认 Success = , //成功 Failure = ,//失败 ServerError = ,//服务错误 Others = //其它
}
}
在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) && "".Equals(pwd))
{
UserIdEntity identity = new UserIdEntity() { Account = name, PassWord = pwd, role = "" };
//创建Form票据
FormsAuthenticationTicket ticket = new FormsAuthenticationTicket(, name, DateTime.Now, DateTime.Now.AddHours(), 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);
}
要跳转的页面,这里只允许角色Id为(1,2,3)中的其中的一个进入。且[Roles=""]标记为固定写法
[UserAuthorize(Roles="1,2,3")]
public ActionResult Main()
{
return View();
}
退出登陆
[AllowAnonymous] //允许匿名
public ActionResult OutLogon()
{
Session.Abandon();
FormsAuthentication.SignOut();
return RedirectToAction("Index","Home");
}
在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方法
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web; using System.Net.Http;
using Solution.Common;
using System.Web.Http.Controllers;
using System.Web.Http.Filters;
namespace Solution.Filter
{
public class SecreKeyAttribute : ActionFilterAttribute
{ public override void OnActionExecuting(System.Web.Http.Controllers.HttpActionContext actionContext)
{ ResponseMsg response = new ResponseMsg() { Status = ActonState.Default }; //var Ticket = actionContext.ActionArguments["Ticket"];//get请求时带的参数 var Ticket = System.Web.HttpContext.Current.Request["Ticket"]; if (Ticket == null)
{
response.Msg = "请传入密钥!";
actionContext.Response = actionContext.Request.CreateResponse(System.Net.HttpStatusCode.OK, response);
}
else
{
string SecrtetKey = Ticket.ToString();
if (!SecrtetKey.Equals(""))
{
response.Msg = "密钥错误!";
actionContext.Response = actionContext.Request.CreateResponse(System.Net.HttpStatusCode.OK, response);
}
}
base.OnActionExecuting(actionContext); } public override void OnActionExecuted(HttpActionExecutedContext actionExecutedContext)
{ base.OnActionExecuted(actionExecutedContext);
} }
}
编写WebApiConfig配置文件,
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Http; namespace Solution.Models
{
public class WebApiConfig
{
public static void Register(HttpConfiguration config)
{
//config.MapHttpAttributeRoutes(); config.Routes.MapHttpRoute(
name: "DefaultApi",//默认请求api地址
routeTemplate: "api/{controller}/{action}/{id}", //例如:
http://localhost:41464/api/ScreateKey/GetInfo
defaults: new { id = RouteParameter.Optional });
}
}
}
在Golba.asax中Application_Start()方法下加入刚才的WebApi文件配置
WebApiConfig.Register(GlobalConfiguration.Configuration);
创建对应的api方法,并加入 [SecreKey]标签
using Solution.Common;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Http; using System.Net;
using System.Net.Http;
using Solution.Filter; namespace Solution.Controllers
{
public class ScreateKeyController : ApiController
{ // GET: ScreateKey
[SecreKey]
[HttpPost]
public ResponseMsg GetInfo([FromBody]string Ticket)
{
ResponseMsg response = new ResponseMsg() { Status = ActonState.Default };
response.Msg = "密钥正确时,会返回这个结果";
return response;
}
}
}
注:这里用的是post请求。 参数必须带上这个[FromBody],不然请求不到。而且这个[FromBody]只能用一次,如果有多个参数就只能封装到一个类里面。
测试一下。正确密钥 “8888888”
密钥错误:

密钥正确:

三。结果过滤
添加一个过滤特性类
using Solution.Common;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc; namespace Solution.Filter
{
public class ResultAttribute : ActionFilterAttribute
{
public override void OnResultExecuting(ResultExecutingContext resultContext)
{
ResponseMsg response = new ResponseMsg() { Status = ActonState.Default };
resultContext.HttpContext.Response.Write("<br/> 结果返回之前执行");
base.OnResultExecuting(resultContext);
} public override void OnResultExecuted(ResultExecutedContext resultContext)
{
ResponseMsg response = new ResponseMsg() { Status = ActonState.Default };
resultContext.HttpContext.Response.Write("<br/> 结果返回之后执行");
base.OnResultExecuted(resultContext);
}
}
}
在Home控制器添加一个视图,并添加[Result]标签
[Result]
public ActionResult FunResult()
{
return View();
}
在FunResult.cshtml页面加入如下代码:
@{
Response.Write("<br/> 返回的结果");
}
测试一下,得到结果如下图:

四。异常过滤
创建一个发生错误时跳转的页面
添加一个异常过滤特性类
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web; using System.Web.Mvc; namespace Solution.Filter
{
//异常过滤器
public class HandErrorAttribute :HandleErrorAttribute
{
//程序中任何一个地方发生异常都会处理
public override void OnException(ExceptionContext filterContext)
{
//获取异常对象
Exception ex = filterContext.Exception; //记录日志 //发生错误后,跳转的页面
filterContext.Result = new RedirectResult("/Home/Error"); //告知异常已被处理。如果没有则按照系统正常的异常处理流程走!
filterContext.ExceptionHandled = true; }
}
}
在App_Start文件夹下创建FilterConfig文件
using Solution.Filter;
using System.Web;
using System.Web.Mvc; namespace Solution
{
public class FilterConfig
{
public static void RegisterGlobalFilters(GlobalFilterCollection filters)
{
filters.Add(new HandErrorAttribute());
}
}
}
在Glabal.asa文件Application_Start()方法下添加刚才的筛选配置
FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
.Net Mvc 四种过滤器的更多相关文章
- 第四节:MVC中AOP思想的体现(四种过滤器)并结合项目案例说明过滤器的实际用法
一. 简介 MVC中的过滤器可以说是MVC框架中的一种灵魂所在,它是MVC框架中AOP思想的具体体现,所以它以面向切面的形式无侵入式的作用于代码的业务逻辑,与业务逻辑代码分离,一经推出,广受开发者的喜 ...
- ASP.NET MVC中有四种过滤器类型
在ASP.NET MVC中有四种过滤器类型
- asp.net mvc 三种过滤器
前几天面试遇到这个问题,发现不是很了解,学习了下,这里记录下来 经常需要将用户的操作记录到日志中,或者是验证用户是否登录了网站, 面对这样的需求,以前的操作是自定义一个统一的全局方法,然后做处理, 在 ...
- ASP.NET MVC 四种传值方法
1.后台传值: public class DataController : Controller { // GET: Data public ActionResult Index() { //1 Vi ...
- net MVC 四种基本 Filter
四种基本 Filter 概述 MVC框架支持的Filter可以归为四类,每一类都可以对处理请求的不同时间点引入额外的逻辑处理.这四类Filter如下表: 使用内置的Authorization Fi ...
- ASP.NET MVC 四种Controller向View传值方法
控制器: // Get: Data public ActionResult Index() { //ViewData 方式 ViewData["UserName"] = " ...
- ASP.NET MVC 主要的四种过滤器和三种具体实现类
4种常用过滤器(IAuthrorizationFilter.IActionFilter.IResultFilter.IExceptionFilter) 和 3种具体实现类(AuthorizeAttri ...
- 你想要的都在这里,ASP.NET Core MVC四种枚举绑定方式
前言 本节我们来讲讲在ASP.NET Core MVC又为我们提供了哪些方便,之前我们探讨过在ASP.NET MVC中下拉框绑定方式,这节我们来再来重点看看枚举绑定的方式,充分实现你所能想到的场景,满 ...
- ASP.NET Core MVC四种枚举绑定方式
前言 本节我们来讲讲在ASP.NET Core MVC又为我们提供了哪些方便,之前我们探讨过在ASP.NET MVC中下拉框绑定方式,这节我们来再来重点看看枚举绑定的方式,充分实现你所能想到的场景,满 ...
随机推荐
- Mac电脑Tomcat下载及安装(详细)
下载Tomcat 1.打开Apache Tomcat官网,选择你需要的版本进行下载: 地址http://tomcat.apache.org/download-70.cgi 2.解压apache-t ...
- C#三层架构实例
对于三层的概念查也查了,看也看了,下面是我找的一个关于三层的简单实例,真正看一下它是如何具体实现的. 我们先来一起看看 实体类-Model 实质:实体类就是在完成数据库与实体类对应的功能,一个类是一张 ...
- Unity3D的坑系列:打包Assetbundle丢失Shader问题(贴图显示不了)
从Unity4.2开始,为了减少首包大小,不会默认将所有Shader引擎加到游戏程序中,据Unity技术支持人员所说,Unity会将Shader引擎打包到Assetbundle资源中,但是我测试发现不 ...
- Dev TreeList基本用法
public partial class treelist_shijian : DevExpress.XtraEditors.XtraForm { public treel ...
- flask系列五之flask_script
1.一个简单的例子 在工程里面新建一个Python文件命名为manage.py (1)安装flask_script包,然后引入 from flask_script import Manager fro ...
- Internet Explorer 无法打开该 Internet 站点,请求的站点不可用或无法找到
笔者最近遇见一个神奇的问题,同事在开发时用的谷歌浏览器,实现了一个下载功能,测试也没问题:但测试人员反馈说他那边没法下载,报异常.弹出框 同事跑过来和我商讨这个问题,笔者当时就懵了,于是赶紧查找相关资 ...
- Just a Hook(树状数组)
In the game of DotA, Pudge’s meat hook is actually the most horrible thing for most of the heroes. T ...
- SonarQube在CentOS上的安装
1 简介 SonarQube 是一个用于代码质量管理的开放平台.通过插件机制,Sonar 可以集成不同的测试工具,代码分析工具,以及持续集成工具.与持续集成工具(例如 Hudson/Jenkins 等 ...
- MySQL与SQLServer的update left join语法区别
需求: 表A 字段 A_ID, A_NAME, B_ID 表B 字段 B_ID, B_NAME 需求把A的所有A_NAME更新为相应的B的 B_NAME. mysql做法: UPDATE A LEFT ...
- libevent源码深度剖析四
libevent源码深度剖析四 ——libevent源代码文件组织 1 前言 详细分析源代码之前,如果能对其代码文件的基本结构有个大概的认识和分类,对于代码的分析将是大有裨益的.本节内容不多,我想并不 ...