先介绍下什么是过滤器:ASP.NET MVC中的灭一个请求,都会分配给相应的控制器和对应的行为方法去处理,而在这些处理的前前后后如果想再加一些额外的逻辑处理,这时就用到了过滤器。
MVC支持的过滤器有四种:Authorization(授权)、Action(行为)、Result(结果)、Exception(异常)
默认实现的过滤器如下:
一、授权过滤器
给Index页面,添加授权过滤器,只有当用户名为admin1和admin,密码是123456时,才可以访问index页面。
1.无参数的授权过滤器
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
[Authorize]
public
ActionResult Index()
{
return
View();
}
public
ActionResult Login(LoginModel login)
{
if
((login.UserName ==
"admin1"
|| login.UserName ==
"admin"
) && login.Password ==
"123456"
)
{
FormsAuthentication.SetAuthCookie(login.UserName,
false
);
return
Redirect(
"/Home/Index"
);
}
return
View();
}
|
此时,我们执行捷星程序,会发现报出无授权的错误,如下
这是由于Web.Config 中缺少如下代码:
1
2
3
|
<authentication mode=
"Forms"
>
<forms loginUrl=
"~/Home/Login"
timeout=
"1"
/>
</authentication>
|
此时,再次执行则会跳转至登录界面。
2.有参数的授权过滤器
[Authorize(Users = "admin,admin1")],可以实现和上面无参相同的功能
[Authorize(Users = "admin")],此时,只有UserName为amin时,才会跳转至index页面。
二、HandleError过滤器
1、MVC默认错误页面
定义一个界面抛出异常,此时会进去MVC默认的错误页面,即Views/Shared下的Error.cshtml
1
2
3
4
5
6
|
//处理错误过滤器HandleError
[HandleError(ExceptionType =
typeof
(Exception))]
public
ActionResult ThrowError()
{
throw
new
Exception(
"this is ThrowErrorLogin Action Throw"
);
}
|
执行结果如下:
2、自定义错误页面
自定义一个错误页面MyError.cshtml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
|
@{
Layout =
null
;
}
<!DOCTYPE html>
<html>
<head>
<title>MyErrorPage</title>
</head>
<body>
<div>
<p>
There was a <b>@Model.Exception.GetType().Name</b>
while
rendering <b>@Model.ControllerName</b>'s
<b>@Model.ActionName</b> action.
</p>
<p style=
"color:Red"
>
<b>@Model.Exception.Message</b>
</p>
<p>Stack trace:</p>
<pre style=
" background-color:Orange"
>@Model.Exception.StackTrace</pre>
</div>
</body>
</html>
|
此时在方法前加上[HandleError(ExceptionType = typeof(Exception), View = "MyError")],则调用抛出异常的界面,则会跳转至我们自定义的错误界面
三、自定义过滤器
自定义过滤器需要继承ActionFilterAttribute抽象类,重写其中的方法。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
|
public
abstract
class
ActionFilterAttribute : FilterAttribute, IActionFilter, IResultFilter
{
//
// 摘要:
// 初始化 System.Web.Mvc.ActionFilterAttribute 类的新实例。
protected
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);
}
|
1、不带参数的自定义过滤器
这里定义一个自定义的登录过滤器,用户名和密码为空,或者不为damin和123456,则会跳转至登录页面
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
|
public
class
CheckLogin: ActionFilterAttribute
{
public
override
void
OnActionExecuting(ActionExecutingContext filterContext)
{
HttpCookieCollection CookieCollect = System.Web.HttpContext.Current.Request.Cookies;
if
(CookieCollect[
"username"
] ==
null
|| CookieCollect[
"password"
] ==
null
)
{
filterContext.Result =
new
RedirectResult(
"/Home/Login"
);
}
else
{
if
(CookieCollect[
"username"
].Value !=
"admin"
&& CookieCollect[
"password"
].Value !=
"123456"
)
{
filterContext.Result =
new
RedirectResult(
"/Home/Login"
);
}
}
}
}
|
使用时只需要在方法名前加上[CheckLogin]即可。
2、带参数的自定义过滤器
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
|
public
class
ParamsFilter : ActionFilterAttribute
{
public
string
Message {
get
;
set
; }
public
override
void
OnActionExecuting(ActionExecutingContext filterContext)
{
base
.OnActionExecuting(filterContext);
filterContext.HttpContext.Response.Write(
"Action执行之前"
+ Message +
"<br />"
);
}
public
override
void
OnActionExecuted(ActionExecutedContext filterContext)
{
base
.OnActionExecuted(filterContext);
filterContext.HttpContext.Response.Write(
"Action执行之后"
+ Message +
"<br />"
);
}
public
override
void
OnResultExecuting(ResultExecutingContext filterContext)
{
base
.OnResultExecuting(filterContext);
filterContext.HttpContext.Response.Write(
"返回Result之前"
+ Message +
"<br />"
);
}
public
override
void
OnResultExecuted(ResultExecutedContext filterContext)
{
base
.OnResultExecuted(filterContext);
filterContext.HttpContext.Response.Write(
"返回Result之后"
+ Message +
"<br />"
);
}
}
|
这个自定一过滤器定义了一个string类型的参数,使用时在Action上加[ParamsFilter(Message = "test")]
四、如果一个Control中所有的Action都需要用到同一个过滤器,则可以直接在Control上面加此过滤器