MVC之ActionFilterAttribute自定义属性

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

posted @ 2016-03-01 06:28  BloggerSb  阅读(631)  评论(0编辑  收藏  举报