ActionFilterAttribute里有OnActionExecuting方法,跟Controller一样, 同是抽象实现了IActionFilter接口。
// 登录认证特性 public class AuthenticationAttribute : ActionFilterAttribute { public override void OnActionExecuting(ActionExecutingContext filterContext) { if (filterContext.HttpContext.Session["username"] == null) filterContext.Result = new RedirectToRouteResult("Login", new RouteValueDictionary { { "from", Request.Url.ToString() } }); base.OnActionExecuting(filterContext); } }
使用方法如下:
public class HomeController : Controller { [Authentication] public ActionResult Index() { return View(); } }
如果你想针对整个MVC项目的所有Action都使用此过滤器,步骤如下:
a. 确保Global.asax.cs的Application_Start方法中包含如下红色行:
public class MvcApplication : System.Web.HttpApplication { protected void Application_Start() { AreaRegistration.RegisterAllAreas(); WebApiConfig.Register(GlobalConfiguration.Configuration); FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters); RouteConfig.RegisterRoutes(RouteTable.Routes); } }
b. 在FilterConfig.cs文件中注册相应的特性过滤器:
public class FilterConfig { public static void RegisterGlobalFilters(GlobalFilterCollection filters) { filters.Add(new HandleErrorAttribute()); filters.Add(new AuthenticationAttribute()); } }
如此,通过过滤器的方法实现认证和授权
另有不推荐的方法实现授权功能,自定义一个控制器类,再通过继承这个控制器类:
1、继承Controller:
1.1 参考WebForm使用方式,在派生类里自己添加了验证方法,然后在每个Action方法里调用。
派生类如下:
public class AuthenticationControllor : Controller { public bool Validate() { if (Session["username"] == null) return false; else return true; } public ActionResult RedirectLogin(bool redirect = true) { if (redirect) return RedirectToAction("Login", "Home", new { from = Request.Url.ToString() }); else return RedirectToAction("Login", "Home"); } }
使用类如下:
public class HomeController : AuthenticationControllor { public ActionResult Index() { if (!Validate()) return RedirectLogin(); return View(); } }
1.2 改进上面的使用,通过用Controller里有一个OnActionExecuting方法,此方法是在Action之前执行的,非常方便。
派生类如下:
public class AuthenticationControllor : Controller { protected override void OnActionExecuting(ActionExecutingContext filterContext) { if (filterContext.HttpContext.Session["username"] == null) filterContext.Result = new RedirectToRouteResult("Login", new RouteValueDictionary { { "from", Request.Url.ToString() } }); base.OnActionExecuting(filterContext); } }
使用类如下:
// 不需要多写任何逻辑代码就能判断是否登录并跳转 public class HomeController : AuthenticationControllor { public ActionResult Index() { return View(); } }
/// <summary> /// 权限拦截 /// </summary> [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = false)] public class PermissionFilterAttribute : ActionFilterAttribute { /// <summary> /// 权限拦截 /// </summary> /// <param name="filterContext"></param> public override void OnActionExecuting(ActionExecutingContext filterContext) { if (!this.CheckAnonymous(filterContext)) { //未登录验证 if (SessionHelper.Get("UserID") == null) { //跳转到登录页面 filterContext.RequestContext.HttpContext.Response.Redirect("~/Admin/User/Login"); } } } /// <summary> /// [Anonymous标记]验证是否匿名访问 /// </summary> /// <param name="filterContext"></param> /// <returns></returns> public bool CheckAnonymous(ActionExecutingContext filterContext) { //验证是否是匿名访问的Action object[] attrsAnonymous = filterContext.ActionDescriptor.GetCustomAttributes(typeof(AnonymousAttribute), true); //是否是Anonymous var Anonymous = attrsAnonymous.Length == 1; return Anonymous; } }
通过写一个BaseController来进行权限的验证,这样就不需要所有需要验证的Controller加标注了,当然BaseController还可以增加其他通用的处理
/// <summary> /// Admin后台系统公共控制器(需要验证的模块) /// </summary> [PermissionFilter] public class BaseController:Controller { }
Action跳转小结 一、RedirectToAction("Index");//一个参数时在本Controller下,不传入参数。 二、RedirectToAction(ActionName,ControllerName) //可以直接跳到别的Controller. 三、RedirectToRoute(new {controller="Home",action="Index"});//可跳到其他controller 四、RedirectToRoute(new {controller="Home",action="Index", id=param});//可跳到其他controller,带参数。 五、Response.Redirect("Index?id=1");//适用于本controller下的方法名称,可带参数。 六、return Redirect("Index");//适用于本controller下的方法名称。 七、return View("Index"); //直接显示对应的页面 不经过执行Controller的方法。 八、return View("~/Views/Home/Index.aspx");//这种方法是写全路径,直接显示页面,不经过Controller方法 九、return View();//直接显示页面,不经过Controller方法
其它文章 :
http://www.cnblogs.com/sunkaixuan/p/4908773.html