MVC 自定义过滤器(Filter)可以实现路由控制、异常处理、授权处理(获取客户端信息)
由于Controller 实现了 IActionFilter 、IAuthorizationFilter、IExceptionFilter 等几个过滤器接口,故可以自定义类实现这几个接口 然后在 FilterConfig.cs文件中 注册这几个过滤器 实现切面控制,具体代码如下:
FilterConfig.cs
//将自定义异常过滤器的优先级提高,防止异常被默认的HandleError处理(也可以自定义类重写HandleErrorAttribute 实现错误处理) filters.Add(new SystemIExceptionFilter(), 1); //控制器过滤器 filters.Add(new SystemIActionFilter(), 2); //授权过滤器 filters.Add(new SystemIAuthorizationFilter(), 3);
路由访问过滤器
public class SystemIActionFilter : IActionFilter { // // Summary: // Called after the action method is invoked. // 在Action返回之后 // Parameters: // filterContext: // Information about the current request and action. public void OnActionExecuted(ActionExecutedContext filterContext) { } // // Summary: // Called before the action method is invoked. // 在进入Action之前 // 说明:使用RedirectToRouteResult进行路由值进行重定向时 // RouteName 路由名称 // RouteValues 路由值 特别注意第三个值 Permanent 获取一个值 // 该值指示重定向是否应为永久重定向 如果为true 在本程序会出现问题 // Parameters: // filterContext: // Information about the current request and action. public void OnActionExecuting(ActionExecutingContext filterContext) { //验证 控制器 视图 string tempAction = filterContext.RouteData.Values["action"].ToString(); string tempController = filterContext.RouteData.Values["controller"].ToString(); string tempLoginAction = filterContext.RouteData.Values["action"].ToString(); if (tempAction == "HomeLogin" && tempController == "Home" || tempLoginAction == "UserLogin" ? false : true) { //请求登录时 if (tempAction == "UserLogin" && tempController == "Home" ? false : true) { //Cookie HttpCookie tempToken = filterContext.HttpContext.Request.Cookies["exclusiveuser_token"]; if (tempToken == null) { filterContext.Result = new RedirectToRouteResult("HomeLogin", new RouteValueDictionary(new { controller = "Home", action = "HomeLogin" }), false); } //登录token不为null时 进行合法性验证token 头部,载荷,签名,cookie过期时间 if (tempToken == null ? false : true) { //UserToken 方法 将验证 token 合法性 包括token 签名 ,token载荷,cookie 过期时间等 string SystemToken = new SecondTrackToken().UserToken(); if (SystemToken == null) { filterContext.Result = new RedirectToRouteResult("HomeLogin", new RouteValueDictionary(new { controller = "Home", action = "HomeLogin" }), false); }; } } } } }
异常处理过滤器
public class SystemIExceptionFilter : IExceptionFilter { void IExceptionFilter.OnException(ExceptionContext filterContext) { Exception exception = filterContext.Exception; if (filterContext.ExceptionHandled) { return; } HttpException http = new HttpException(null, exception); /* * filterContext.Exception.Message 错误信息 */ string messager = filterContext.Exception.Message; /* * 错误日志 */ Log4NetHelp help = new Log4NetHelp(); help.ErrorString(filterContext.Exception.Message); /* * 设置自定义异常已经处理,避免其他过滤器异常覆盖 */ filterContext.ExceptionHandled = true; /* * 在派生类重写时,设置或者重写一个值该值指定是否禁用ISS7.0中自定义错误 */ filterContext.HttpContext.Response.TrySkipIisCustomErrors = true; } }
授权处理(获取客户端信息)
public class SystemIAuthorizationFilter : IAuthorizationFilter { void IAuthorizationFilter.OnAuthorization(AuthorizationContext filterContext) { //当前操作计算机用户 string pcName = ((System.Web.HttpServerUtilityWrapper)((System.Web.HttpContextWrapper)filterContext.RequestContext.HttpContext).Server).MachineName; //视图 string action = ((System.Web.Mvc.ReflectedActionDescriptor)filterContext.ActionDescriptor).ActionName; //控制器 string controller = ((System.Web.Mvc.ReflectedActionDescriptor)filterContext.ActionDescriptor).ControllerDescriptor.ControllerName; //请求时间 string time = filterContext.RequestContext.HttpContext.Timestamp.ToString(); //请求相对路径 string absturl = ((System.Web.UnvalidatedRequestValuesWrapper)((System.Web.HttpRequestWrapper)((System.Web.HttpContextWrapper)filterContext.RequestContext.HttpContext).Request).Unvalidated).Url.AbsoluteUri; //状态 string code = ((System.Web.HttpResponseWrapper)((System.Web.HttpContextWrapper)filterContext.RequestContext.HttpContext).Response).Status; // 浏览器版本 string browser = ((System.Web.HttpBrowserCapabilitiesWrapper)((System.Web.HttpRequestWrapper)((System.Web.HttpContextWrapper)filterContext.RequestContext.HttpContext).Request).Browser).Type; //请求方式 string gepPost = ((System.Web.HttpRequestWrapper)((System.Web.Mvc.Controller)filterContext.Controller).Request).RequestType; //本地主机名称解析DNS本身处理。 string server = ((System.Web.HttpRequestWrapper)((System.Web.HttpContextWrapper)filterContext.HttpContext).Request).UserHostAddress; #region server 说明 /* * 版权(c)1993 - 2009微软(msft . o:行情)。 * * 这是一个示例所使用的主机文件微软为Windows TCP / IP。 * * 这个文件包含IP地址到主机名的映射。 每一个 * 条目应该保存在单个行。 IP地址应 *被放置在第一列对应的主机名。 *的IP地址和主机名应该由至少一个 *空间。 * *此外,评论(这样的)可能是插入的个人 *线或后机器名称用“*”符号。 * 例如: * * 102.54.94.97 rhino.acme.com源服务器 * 38.25.63.10 x.acme.com x客户机主机 *本地主机名称解析DNS本身处理。 * 127.0.0.1 localhost *::1 localhost */ #endregion //用户 //部门 //职位 } }