Asp.Net MVC过滤器小试牛刀
在上学期间学习的Asp.Net MVC,基本只是大概马马虎虎的了解,基本处于知其然而不知其所以然。现在到上班,接触到真实的项目,才发现还不够用,于是从最简单的过滤器开始学习。不得不说MVC的过滤器真是简单,而又不失优雅。
以前我写异常都是try...catch...配合log4net来记录日志,这真是一个重复造轮子的过程,一不小心还会忘记。后面在开发的过程中,逐渐学习到过滤器(Filter)这一优雅的东东,一下子爱上了它。
在Asp.Net MVC有最基本的过滤器,添加一个Home控制器,然后添加两个Action,这里为了演示,添加了两个同名的Action,为了编译,设置了参数的区别,实际上并没有使用参数。
public class HomeController : Controller
{
[HttpGet]
public ActionResult Index(string msg)
{
return Content("I'm come from Get Method.");
} [HttpPost]
public ActionResult Index()
{
return Content("I'm come from Post Method.");
}
}
点击调试,使用PostMan分别用get/post方式去访问Home/Index,如下图:

对于同一个Action,只是请求方式不一样,返回的结果也不一样,这就是Asp.Net最基本的过滤器。
[HttpGet]:该Action只响应get请求
[HttpPost]:该Action只响应post请求
于是我们可以思考,是不是可以考虑将很多重复的代码封装起来,例如判断用户是否有权限访问该Action,只需要简单的在Action上做一个特性标注就可以或者注册一个全局的机制,满足需要?很好,Asp.Net给我们提高了简单优雅的过滤器。
下面来简单看一下我自己写的权限判断过滤器。
1,在项目中添加Filters文件夹,所有Filters都放置在该文件夹中,方便后期归档
2,在Filters文件夹中添加一个类:CheckUserRoleAttribute.cs,在这里我们按照MVC约定的方式来命名,过滤器以Attribute来结尾。让其继承: System.Web.Mvc.ActionFilterAttribute。查看ActionFilterAttribute定义,其成员如下:
// 摘要:
// 在执行操作方法后由 ASP.NET MVC 框架调用。
//
// 参数:
// filterContext:
// 筛选器上下文。
public virtual void OnActionExecuted(ActionExecutedContext filterContext);
//
// 摘要:
// 在执行操作方法之前由 ASP.NET MVC 框架调用。
//
// 参数:
// filterContext:
// 筛选器上下文。
public virtual void OnActionExecuting(ActionExecutingContext filterContext);
//
// 摘要:
// 在执行操作结果后由 ASP.NET MVC 框架调用。
//
// 参数:
// filterContext:
// 筛选器上下文。
public virtual void OnResultExecuted(ResultExecutedContext filterContext);
//
// 摘要:
// 在执行操作结果之前由 ASP.NET MVC 框架调用。
//
// 参数:
// filterContext:
// 筛选器上下文。
public virtual void OnResultExecuting(ResultExecutingContext filterContext);
看注解可以知道4个成员:
OnActionExecuted
OnActionExecuting
OnResultExecuted
OnResultExecuted
而我一般都是重写OnActionExecuting方法:
public class CheckUserRoleAttribute : System.Web.Mvc.ActionFilterAttribute
{
public override void OnActionExecuting(System.Web.Mvc.ActionExecutingContext filterContext)
{
/*
* 这里为了方便演示,直接在请求参数中获取了userName
* 假设某一个Action只有Lucy可以访问。
*/
string userName = filterContext.HttpContext.Request["userName"];
if (userName=="Lucy")
{
base.OnActionExecuting(filterContext);
return;
}
else
{
//这里构造了一个心得ActionResult.如果userName不是Lucy,则返回权限不足
filterContext.Result = new System.Web.Mvc.ContentResult() { Content = "权限不足,无法访问" };
return;
}
}
}
然后在HomeController中添加SayHello(),并且添加特性[CheckUserRole]
public class HomeController : Controller
{
[HttpGet]
public ActionResult Index(string msg)
{
return Content("I'm come from Get Method.");
} [HttpPost]
public ActionResult Index()
{
return Content("I'm come from Post Method.");
} //添加特性
[Filters.CheckUserRole]
public ActionResult SayHello()
{
return Content("我是Lucy,这只能给我访问");
}
}
点击调试:

这样子,一个简单的过滤器就实现了。
我们可以根据实际的逻辑去重写自己的过滤器。
**********************简单优雅的分隔符**********************
另外一个比较常用的是异常过滤器
1,同样新建SystemErrorAttribute.cs
需要注意,这里继承的是:System.Web.Mvc.HandleErrorAttribute
public class SystemErrorAttribute : System.Web.Mvc.HandleErrorAttribute
{
public override void OnException(ExceptionContext filterContext)
{
base.OnException(filterContext);
//处理错误消息,将其跳转到一个页面
string controllerName = (string)filterContext.RouteData.Values["controller"];
string actionName = (string)filterContext.RouteData.Values["action"];
//这里简单向C盘的test.log写入了文件
FileStream fs = new FileStream(@"C:\test.log", FileMode.OpenOrCreate, FileAccess.Write);
StreamWriter sw = new StreamWriter(fs);
sw.BaseStream.Seek(, SeekOrigin.End);
string writeText = string.Format("controllerName:[{0}]actionName:[{1}]{2}",
controllerName, actionName, filterContext.Exception.ToString());
sw.WriteLine(writeText);
sw.Flush();
sw.Close();
fs.Close(); /*//这里是使用log4net来记录
log4net.ILog log = log4net.LogManager.GetLogger("controllerName:[" + controllerName + "]actionName:[" + actionName+"]");
log.Error(filterContext.Exception.ToString());
*/ //錯誤友好輸出,这里重新构造了一个ActionResult
filterContext.Result = new System.Web.Mvc.ContentResult() { Content = "系统错误,请联系管理员" };
return;
}
}
2,在HomeController中添加MyError()
public class HomeController : Controller
{
[Filters.SystemError]//添加
public ActionResult MyError()
{
//人为制造一个错误
int a = ;
int b = ;
return Content((a/b).ToString());
}
}
3,调试:注意:这里需要采用Ctrl+F5的方式运行,结果如下:

到这里,可能会有很大疑问,为什么没有产生友好提示呢?在过滤器中不是明明有添加友好提示吗?
先看一下C盘的日志:test.log

日志有成功产生。没有出现友好提示的原因在于不是正式的环境,VS为了方便调试,不会隐藏错误信息。下面将应用部署到真实的环境中去调试,看结果:

这下友好提示又出来了。。。
当然对于异常处理过滤器来说,我在每个Action都来添加特性,还是很麻烦,这里我们就要注册成为全局过滤器:
①,打开App_Start文件夹中的FilterConfig.cs
添加:filters.Add(new Filters.SystemErrorAttribute());
public class FilterConfig
{
public static void RegisterGlobalFilters(GlobalFilterCollection filters)
{
//添加这个
filters.Add(new Filters.SystemErrorAttribute()); filters.Add(new HandleErrorAttribute());
}
}
②,在HomeController去掉[Filters.SystemError]特性,然后发布,调试结果:结果一样

就这样,全局异常处理就完成了。
========================
由于学识有限,文章难免會有错误,敬请指教与批评。
Asp.Net MVC过滤器小试牛刀的更多相关文章
- ASP.NET MVC 过滤器(一)
ASP.NET MVC 过滤器(一) 前言 前面的篇幅中,了解到了控制器的生成的过程以及在生成的过程中的各种注入点,按照常理来说篇幅应该到了讲解控制器内部的执行过程以及模型绑定.验证这些知识了.但是呢 ...
- ASP.NET MVC 过滤器(三)
ASP.NET MVC 过滤器(三) 前言 本篇讲解行为过滤器的执行过程,过滤器实现.使用方式有AOP的意思,可以通过学习了解过滤器在框架中的执行过程从而获得一些AOP方面的知识(在顺序执行的过程中, ...
- ASP.NET MVC 过滤器(四)
ASP.NET MVC 过滤器(四) 前言 前一篇对IActionFilter方法执行过滤器在框架中的执行过程做了大概的描述,本篇将会对IActionFilter类型的过滤器使用来做一些介绍. ASP ...
- ASP.NET MVC 过滤器(五)
ASP.NET MVC 过滤器(五) 前言 上篇对了行为过滤器的使用做了讲解,如果在控制器行为的执行中遇到了异常怎么办呢?没关系,还好框架给我们提供了异常过滤器,在本篇中将会对异常过滤器的使用做一个大 ...
- ASP.NET没有魔法——ASP.NET MVC 过滤器(Filter)
上一篇文章介绍了使用Authorize特性实现了ASP.NET MVC中针对Controller或者Action的授权功能,实际上这个特性是MVC功能的一部分,被称为过滤器(Filter),它是一种面 ...
- Asp.net Mvc 过滤器执行顺序
Asp.net Mvc 过滤器执行顺序: IAuthorizationFilter(OnAuthorization)----->IActionFilter(OnActionExecuting)- ...
- ASP.NET MVC过滤器
在ASP.NET MVC中有个重要特性就是过滤器,使得我们在MVC程序开发中更好的控制浏览器请求的URL,不是每个请求都有响应内容,只有特定得用户才有.园子里关于过滤器的资料也有很多,这篇文章主要是记 ...
- ASP.NET MVC过滤器(一)
MVC过滤器是加在 Controller 或 Action 上的一种 Attribute,通过过滤器,MVC 网站在处理用户请求时,可以处理一些附加的操作,如:用户权限验证.系统日志.异常处理.缓存等 ...
- ASP.NET MVC 过滤器开发与使用
ASP.NET MVC 中给我们提供了内置的过滤器,通过过滤器,我们可以在控制器内的方法前后,添加必须的业务逻辑,如权限验证,身份验证,错误处理等. 今天,我们主要介绍3个过滤器:OutputCach ...
随机推荐
- linux-阿里云ECS部署PPTP(centos)
请参考以下步骤:(centos6.5中测试通过) 1.服务器端安装软件 1.1 首先安装ppp,命令: [root@test ~]#yum install -y ppp 提示Complete! ,表示 ...
- [改善Java代码]推荐使用String直接量赋值
建议52:推荐使用String直接量赋值 一.建议 String对象的生成方式有两种: 1.通过new关键字生成,String str3 = new String(“中国”); 2.直接声明,如:St ...
- 关于同步VSS服务器上的代码发生Eclipse里面的项目全部不见了
有次在同步VSS服务器上的代码的时候突然发生了错误(同步的代码的项目竟然消失了)....如下图 Could not open the editor: The file does not exist. ...
- [设计模式]<<设计模式之禅>>抽象工厂模式
1 女娲的失误 上一篇讲了女娲造人的故事.人是造出来了,世界也热闹了,可是低头一看,都是清一色的类型,缺少关爱.仇恨.喜怒哀乐等情绪,人类的生命太平淡了,女娲一想,猛然一拍 脑袋,忘记给人类定义性别了 ...
- HTML5와 CSS3 적용기
HTML5의 DTD 선언 <!DOCTYPE html> HTML5의 인코딩 선언 <meta charset="utf-8"> 그리고나서는 새로 ...
- Java Concurrency - Fork/Join Framework
Normally, when you implement a simple, concurrent Java application, you implement some Runnable obje ...
- ASP判断当前页面上是否有参数ID传递过来
遇到了一个这样的ASP问题: 在当前页面上判断,是否有参数ID传递过来? 如果没有,显示“没有参数传递过来”. 如果有传递,但值为空,显示“存在参数,但参数为空” <% if (request( ...
- 面试之SQL(1)--选出选课数量>=2的学号
ID Course 1 AA 1 BB 2 AA 2 BB 2 CC 3 AA 3 BB 3 CC 3 DD 4 AA NULL NULL 选出选课数量>=2的学号 selectdis ...
- 关于微信response_type参数错误
可能出现问题的几个原因: 1.正确的2.0auth的地址:https://open.weixin.qq.com/connect/oauth2/authorize?appid=1%&redire ...
- mssql 查询效率
(1)临时表.表变量 据说:当数据量<100行数据时使用表变量,数据量较大时使用临时表(可创建索引提高查询效率). 表变量只能创建主键或唯一索引,准确讲是约束不是索引. (2)存储过程直接在查询 ...