下面我们继续之前的ASP.NET MVC学习之过滤器篇(1)进行学习。

3.动作过滤器

顾名思义,这个过滤器就是在动作方法调用前与调用后响应的。我们可以在调用前更改实际调用的动作,也可以在动作调用完成之后更改最终返回的结果,当然很多人一定不太明白这个到底可以干什么,

下面我们举一个比较实际的例子:

相信理解过网站的安全的一定知道跨站请求(CSRF具体可以自行百度,这里我就不去解释了),当然也有解决方案,那就是给页面中增加一个识别码,当页面进行POST请求时,首先判断识别码是否正确,

如果正确则继续进行操作。并且在执行完成之后重新分配一个新的识别码(当然也可以只用一个识别码直到会话结束),这样就可以加大进行跨站请求的难度。而动作过滤器的所处的生命周期刚好符合,

下面我们就开始编写这个过滤器类。

首先我们在Filter文件夹中新建一个ViewMacFilterAttribute类,并且这个类需要继承FilterAttribute,同时还要实现IActionFilter接口:

 namespace MvcStudy.Filter
{
public class ViewMacFilterAttribute : FilterAttribute , IActionFilter
{ public void OnActionExecuted(ActionExecutedContext filterContext)
{
string viewMac = Guid.NewGuid().ToString();
filterContext.HttpContext.Session["vmac"] = viewMac;
filterContext.Controller.ViewBag.ViewMac = viewMac;
} public void OnActionExecuting(ActionExecutingContext filterContext)
{
object viewMac = filterContext.HttpContext.Session["vmac"];
string strMac = filterContext.HttpContext.Request.Form["viewMac"];
filterContext.Result = new HttpNotFoundResult();
if (viewMac != null && strMac != null)
{
if (viewMac.Equals(strMac))
{
filterContext.Result = null;
}
}
}
}
}

这里我们实现了IActionFilter 接口中的OnActionExecuted方法和OnActionExecuting方法,它们分别对应着动作执行结束和动作执行前,通过OnActionExecuting中的代码,我们可以清楚的看到我们首先从Session中获取识别码,然后又从页面中的表单获取客户端的识别码,

这里我们可以看到我们首先默认返回的结果是404,如果比配成功则将Result设置为NULL,如果ResultNULL是会正常调用对应的活动的。接着就是OnActionExecuted方法中的功能,仅仅只是重新分配一个识别码,并且保存进Session中。

注:这种方式会导致一个页面进行了POST请求之后,识别码变换之后。其他页面的提交功能就会失败,所以还要加以ajax去辅助,或者就是一个用户会话分配一个识别码,直到用户会话结束。

有了这个过滤器之后我们就可以进行实际的测试了,首先我们先在Home控制器中写入如下代码,并在Views/Home下新建Index.cshtml以及List.cshtml,其中List.cshtml中的页面如下所示:

 @{
ViewBag.Title = "List";
} <h2>List</h2>
@using(Html.BeginForm())
{
@Html.Hidden("viewMac", (string)ViewBag.ViewMac)
<input type="submit" value="submit" />
}

然后就是Home控制器:

 namespace MvcStudy.Controllers
{
public class HomeController : Controller
{
[MobilResultFilter]
public ActionResult Index()
{ return View();
} public ActionResult List()
{
string viewMac = Guid.NewGuid().ToString();
Session["vmac"] = viewMac;
ViewBag.ViewMac = viewMac;
return View();
} [ViewMacFilter]
[HttpPost]
public ActionResult List(string action)
{
return View();
}
}
}

这里我们可以看到默认的List动作中会分配识别码,而POST请求对应的List方法加上了我们之前写的过滤器,现在我们可以先打开这页面然后提交,会发现只是刷新了,接着我们把List.cshtml中的@Html.Hidden("viewMac", (string)ViewBag.ViewMac) 删去,重新进入这个页面,在点击提交,就能发现出现了404的错误,这样我们就可以防止跨站请求了。

4.结果过滤器

上面讲的仅仅只是动作过滤器,在动作执行完成之后都会返回一个结果,即使到这里了,我们依然可以修改最终的结果,之前在讲路由器部分的时候,曾今举过一个例子,就是根据UserAgent去判断是否为手机,并跳转到对应的控制器下的对应动作。但是很多时候手机页面与PC页面的数据都是一摸一样的,如果像之前那样就会导致重复代码的出现,那么我们就可以利用结果过滤器,在动作执行完成之后,判断是否为手机从而改变最后呈现的视图。

下面我们继续在Filter文件夹下新建一个MobilResultFilterAttribute类,并且这个类依然要继承FilterAttribute,同时还要实现IResultFilter接口,实现代码如下:

 namespace MvcStudy.Filter
{
public class MobilResultFilterAttribute : FilterAttribute , IResultFilter
{ public void OnResultExecuted(ResultExecutedContext filterContext)
{ } public void OnResultExecuting(ResultExecutingContext filterContext)
{
if (filterContext.HttpContext.Request.UserAgent.Contains("Android"))
{
((ViewResult)filterContext.Result).ViewName = "List";
}
}
}
}

为了能够以最简单的方式说明,所以笔者仅仅判断了UserAgent是否含有Android,如果含有就修改最终的视图名称,这样我们就可以通过注解属性的方式实现,而不需要放在控制器中或者在动作中进行判断。

下面我们依然要以测试为主,我们还是使用Home控制器:

         [MobilResultFilter]
public ActionResult Index()
{ return View();
}

首先我们通过正常的方式访问,然后让Chrome模拟手机进行访问,这个时候我们就可以发现最终的页面会是List而不是Index了

上面的3和4我们都要自己去继承对应的接口,同时还要继承FilterAttribute类,其实ASP.NET MVC中已经为我们写好了一个默认的类,就是ActionFilterAttribute,我们源码中的定义:

 public abstract class ActionFilterAttribute : FilterAttribute, IActionFilter, IresultFilter

它已经继承了FilterAttribute,同时也实现了IActionFilterIResultFilter接口,这样可以可以少记一些关键的名称。

5.无注解属性过滤与全局过滤器

通过之前的几点,大家可以发现我们都是使用注解属性的方式进行过滤,其他我们也可以直接在控制器中实现,比如下面的代码:

 namespace MvcStudy.Controllers
{
public class HomeController : Controller
{
protected override void OnActionExecuted(ActionExecutedContext filterContext)
{
base.OnActionExecuted(filterContext);
} protected override void OnActionExecuting(ActionExecutingContext filterContext)
{
base.OnActionExecuting(filterContext);
} protected override void OnAuthorization(AuthorizationContext filterContext)
{
base.OnAuthorization(filterContext);
} protected override void OnException(ExceptionContext filterContext)
{
base.OnException(filterContext);
} protected override void OnResultExecuted(ResultExecutedContext filterContext)
{
base.OnResultExecuted(filterContext);
} protected override void OnResultExecuting(ResultExecutingContext filterContext)
{
base.OnResultExecuting(filterContext);
} [MobilResultFilter]
public ActionResult Index()
{ return View();
} public ActionResult List()
{
string viewMac = Guid.NewGuid().ToString();
Session["vmac"] = viewMac;
ViewBag.ViewMac = viewMac;
return View();
} [ViewMacFilter]
[HttpPost]
public ActionResult List(string action)
{
return View();
}
}
}

我们可以看到控制器中其实已经实现了上面所有的接口,当然我建议使用注解属性,这样可以尽量的分离关注点,控制器的代码会很杂乱。

关于全局过滤器,唯一的区别就是我们需要在FilterConfig类中的RegisterGlobalFilters方法中使用filters.add增加上面我们所写的过滤器即可,并没有太大的特殊(FilterConfig在App_Start,在ASP.NET MVC 4以上才有这个文件

6.内建过滤器

关于内建过滤器我们这里就列举出来以下,因为上手很快。

RequireHttps   强迫对动作使用Https协议

OutputCache   缓存一个动作方法的输出

ValidateInput   与安全有关的授权过滤器

AsyncTimeout/NoAsyncTimeout  用于异步控制器

ChildActionOnly 只能作为子操作进行调用

到此为止关于过滤器部分就结束了。

下面是之前的前面ASP.NET MVC学习连载:

ASP.NET MVC学习之路由器篇(1)

ASP.NET MVC学习之路由器篇(2)

ASP.NET MVC学习之路由器篇(3)

ASP.NET MVC学习之控制器篇

ASP.NET MVC学习之过滤器篇(1)

ASP.NET MVC学习之过滤器篇(2)的更多相关文章

  1. ASP.NET MVC学习之过滤器篇(1)

    一.前言 继前面四篇ASP.NET MVC的随笔,我们继续向下学习.上一节我们学习了关于控制器的使用,本节我们将要学习如何使用过滤器控制用户访问页面. 二.正文 以下的示例建立在ASP.NET MVC ...

  2. ASP.NET MVC学习之控制器篇扩展性

    原文:ASP.NET MVC学习之控制器篇扩展性 一.前言 在之前的一篇随笔中已经讲述过控制器,而今天的随笔是作为之前的扩展. 二.正文 1.自定义动作方法 相信大家在开发过程一定会遇到动作方法的重名 ...

  3. ASP.NET MVC学习之控制器篇

    一.前言 许久之后终于可以继续我的ASP.NET MVC连载了,之前我们全面的讲述了路由相关的知识,下面我们将开始控制器和动作的讲解. ASP.NET MVC学习之路由篇幅(1) ASP.NET MV ...

  4. ASP.NET MVC学习之视图篇(2)

    继ASP.NET MVC学习之视图(1)学习 4.HTML辅助器 虽然在ASP.NET MVC中我们已经摆脱了ASP.NET的控件,但是对于页面中需要循环标签的情况依然还是存在,可能很多人认为用for ...

  5. ASP.NET MVC学习之控制器篇(二)

    原文链接:http://www.asp.net/learn/mvc/ 这篇教程探索了ASP.NET MVC控制器(controller).控制器动作(controller action)和动作结果(a ...

  6. ASP.NET MVC学习之视图篇(1)

    一.前言 不知道还有多少读者从第一篇开始一直学习到如今,笔者也会一直坚持将ASP.NET MVC的学习完美的结束掉,然后开始写如何配合其他框架使用ASP.NET MVC的随笔.当然笔者后面的随笔如果没 ...

  7. ASP.NET MVC学习之路由篇(3)

    根据路由输出链接 既然是网站开发自然少不了链接,我们已经学会了强大的路由,但是还缺少一步就是能够将这些路由的路径输出到页面,下面我们就开始学习如何输出路由路径. 首先我们的路由注册部分如下所示: 1 ...

  8. ASP.NET MVC学习之路由篇(2)

    7.解决与物理路径的冲突 当发送一个请求至ASP.NET MVC时,其实会检查网站中存不存在这个请求的物理路径文件,如果存在的话,就会直接将这个物理文件返回.但是有时候我们需要它执行控制器的某个方法, ...

  9. ASP.NET MVC学习之路由篇(1)

    1.基本路由 RouteConfig.cs: 1 public class RouteConfig 2 { 3 public static void RegisterRoutes(RouteColle ...

随机推荐

  1. Devexpress VCL Build v2014 vol 15.2.3 发布

    2016年第一个版本,继续修补. New Major Features in 15.2 What's New in VCL Products 15.2 Breaking Changes To lear ...

  2. Mysql命令行中文乱码的解决方法

    环境:Windows 8 64位,Mysql  5.0.96 for Win64 (x86) 数据库本身安装时默认已经是使用utf8编码的了,但在命令行中执行查询时,查询到的中文依然乱码,解决方法如下 ...

  3. 【转】还html标签以本来意义

    说句实话,“div+css”这个词汇不知道害了多少人,也许其提出者本意并没有错,但是跟风者从表现曲解了其意思,认为整个页面就应当是div+css文件的组合.这样做,对于视觉上并没有什么影响,因为还原了 ...

  4. pyhton函数——黑板客老师课程学习

    1.基本语法 语法: def func_name (arguments)  定义 statements return x,y x,y=func_name(para)   调用 作用域: 可以给内置的函 ...

  5. 【BZOJ2756】奇怪的游戏(二分,最小割)

    题意: Blinker最近喜欢上一个奇怪的游戏.这个游戏在一个 N*M 的棋盘上玩,每个格子有一个数.每次 Blinker 会选择两个相邻的格子,并使这两个数都加上 1.现在 Blinker 想知道最 ...

  6. 接收 ajax POST 方式传入的参数

    ----前台--- var list = new Array(); var params = { gencodeid : "test001", value : "01&q ...

  7. An unknown error occurred & “”的 iPhone is busy: Processing symbol files

    An unknown error occurred & ""的 iPhone is busy: Processing symbol files An unknown err ...

  8. cadence学习之原理图——连线

    重点: (1)两种连接方式:Place Net和Place Net Alias (2)交叉线之间的电气连接Place Junction (3)引脚悬空 Place no connect (4)两器件管 ...

  9. color 和 mode

    ------siwuxie095 color 设置默认的控制台前景和背景的颜色 语法:COLOR [attr] attr  用于指定控制台输出的颜色属性,此属性由两个十六进制数字指定, 第一个为背景颜 ...

  10. php设计模式学习之观察者模式

    什么都不说,先看代码: interface userOperateImpl { public function operate($username); } class userLoginLog imp ...