MVC过滤器总结

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/weixin_41556165/article/details/84643461

注册路由 

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using System.Web.Routing;
 
namespace FB.CMS.MvcSite
{
    public class RouteConfig
    {
        public static void RegisterRoutes(RouteCollection routes)
        {
            routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
 
            routes.MapRoute(
                name: "Default",
                url: "{controller}/{action}/{id}",
                defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional },
                namespaces: new string[] { "FB.CMS.MvcSite.Areas.admin.Controllers" }//项目中如果存在多个Home控制器,需要设定Home控制器的名称空间
 
            ).DataTokens.Add("area", "admin") //.DataTokens.Add("area","admin")就表示将区域里的admin区域的Home控制器的Index视图设为默认启动项
            ;
        }
    }
}

 过滤操作

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
 
namespace MVC过滤器.Filters
{
    //自定义一个过滤器
    [MyActionFilter]
    public class MyActionFilterAttribute : ActionFilterAttribute
    {
        //重写OnActionExecuting方法
        public override void OnActionExecuting(ActionExecutingContext filterContext)
        {
            //我们先来了解一下这个filterContext参数:我们知道OnActionExecuting方法是在Action执行之前会被触发执行的一个方法,那就意味着,将来我在这里面写代码,想要知道你这一个OnActionExecuting方法到底是由那一个Action被调用的时候触发的 (因为所有的action方法被执行的时候都会触发OnActionExecuting这个过滤器方法,所以我就像要知道到底是哪个action被执行的时候触发的这个OnActionExecuting方法)
 
            //获取触发当前方法(OnActionExecuting)的Action名字(即:哪个Action方法被执行的时候触发的OnActionExecuting(ActionExecutingContext filterContext))
            string actionName = filterContext.ActionDescriptor.ActionName;
 
            //获取触发当前方法的的Action所在的控制器名字
            string controllerName = filterContext.ActionDescriptor.ControllerDescriptor.ControllerName;
 
            //获取触发当前方法的Action方法的所有参数(因为参数可能有多个,所以它是一个集合,它的返回值类型是IDictionary<string ,object> 下面为了好看,用var替代)
            var paramss = filterContext.ActionParameters;
 
            string str = "";
            if (paramss.Any()) //Any是判断这个集合是否包含任何元素,如果包含元素返回true,否则返回false
            {
                foreach (var key in paramss.Keys) //遍历它的键;(因为我们要获取的是参数的名称s,所以遍历键)
                {
                    str = key + "的值是" + paramss[key];  //paramss[key] 是key的值
                }
            }
 
 
 
            //获取当前请求的上下文
            filterContext.HttpContext.Response.Write("你好,我也好");
 
 
            //将触发当前方法的这个Action方法的返回结果视图换成一个JsonResult  ( filterContext.Result的返回类型就是JsonResult)
 
            //filterContext.Result:获取或设置由操作方法返回的结果。(既然是获取或者设置Action方法的返回结果,那么我们就可以在这里篡改触发当前方法的那个Action方法的返回结果
 
            //例如:触发当前方法的Action方法是这个:public ActionResult Add(){return Content("中国");} 这个Action方法的返回值是一个"中国"文本  那么我们在这里可以通过filterContext.Result来篡改它的返回值。比如这我给他返回一个json
 
            JsonResult json = new JsonResult();
            json.Data = new { status = "1", message = "OK" };
            json.JsonRequestBehavior = JsonRequestBehavior.AllowGet;
 
            filterContext.Result = json;
 
 
            //将触发当前方法的这个Action方法的返回结果视图换成一个另外一个Action
            filterContext.Result = new RedirectResult("/Login/Index");
 
 
 
            //假设我们在MVC项目中添加一个名字为admin的区域,然后再区域下添加一个Home控制器,然后添加一个Index视图。
            //那现在我们访问这个视图的路径就是:http://localhost:5219/admin/home/index
            //获取区域
            var area = filterContext.RouteData.DataTokens;//MVC可以有区域的,这里就是负责存放区域的
 
            //获取区域名称
            var areaName = area["area"];//这个["area"]是写死了的。你根据["area"]就可以取到区域名称,因为区域的key固定就是area  所以这里areaName的值为admin
 
 
            //RouteData
            var rd = filterContext.RouteData; //在这里面可以获取控制名称,ation名称,参数名称
 
            var controlName = rd.Values["Controller"].ToString();
            var actName = rd.Values["Action"].ToString();
 
 
        }
    }
}
重定向
public RedirectToRouteResult  Login()
        {
            return RedirectToAction("Index", "Home",new {name:lisi,age:20});
        }

ASP MVC利用控制器的OnActionExecuting方法,实现过滤,实现Session登录校验

using MyWeb.Model;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
 
namespace MyWeb.WebApp.Controllers
{
    public class BaseController : Controller   //继承Controller
    {
        public UserInfo LoginUser { get; set; }
        
        //复写父类的该方法。执行控制器中的方法之前先执行该方法。从而实现过滤的功能。
        protected override void OnActionExecuting(ActionExecutingContext filterContext)
        {
            base.OnActionExecuting(filterContext);  //调用父类的该方法。
            //if (Session["userInfo"] == null)   //如果未登录
            bool isSucess = false;
            if(Request.Cookies["sessionId"]!=null)
            {
                string sessionId = Request.Cookies["sessionId"].Value;
                //根据该值查Memcache.
                object obj=Common.MemcacheHelper.Get(sessionId);
                if(obj!=null)
                {
                    UserInfo userInfo = Common.SerializeHelper.DeserializeToObject<UserInfo>(obj.ToString());
                   LoginUser = userInfo;
                   isSucess = true;
                   Common.MemcacheHelper.Set(sessionId, obj, DateTime.Now.AddMinutes(20));//模拟出滑动过期时间.
                }
               
                //filterContext.HttpContext.Response.Redirect("/Login/Index");  //这种跳转方式,会继续向下执行Controller的方法并返回ActionResult。
               
            }
            if (!isSucess)
            {
                filterContext.Result = Redirect("/Login/Index");//这种跳转方式直接返回一个ActionResult,不会继续向下执行,而是直接跳转。速度快。
            }
        }
    }
}
using MyWeb.Model;
using MyWeb.Model.EnumType;
using MyWeb.Model.Search;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
 
namespace MyWeb.WebApp.Controllers
{
    public class UserInfoController :BaseController //Controller   //继承自定义的BaseController
    {
        IBLL.IUserInfoService UserInfoService{get;set;}
        public ActionResult Index()
        {
            return View();
        }
 
    }
}

自己写的登录整体实例:

Global.asax中,全局注册过滤器和路由

public class MvcApplication : System.Web.HttpApplication
    {
        private readonly PACSWebEntities _db = ObjectContextFactory.CreatePACSWebEntities();

        public static void RegisterGlobalFilters(GlobalFilterCollection filters)
        {
            filters.Add(new CustomErrorHandler());
            filters.Add(new CustomerFilterAttribute());
            //filters.Add(new HandleErrorAttribute());
        }

        public static void RegisterRoutes(RouteCollection routes)
        {
            routes.IgnoreRoute("{resource}.axd/{*pathInfo}");

            routes.MapRoute(
                "Default", // Route name
                "{controller}/{action}/{id}", // URL with parameters
                new { controller = "Login", action = "Index", id = UrlParameter.Optional } // Parameter defaults
            );

        }

        public static void RegisterWebApi(HttpConfiguration config)
        {
            config.Routes.MapHttpRoute(
                name: "DefaultApi",
                routeTemplate: "api/{controller}/{id}",
                defaults: new { id = RouteParameter.Optional }
            );

            var appXmlType = config.Formatters.XmlFormatter.SupportedMediaTypes.FirstOrDefault(t => t.MediaType == "application/xml");
            config.Formatters.XmlFormatter.SupportedMediaTypes.Remove(appXmlType);
        }

在应用程序启动时执行

protected void Application_Start()
        {
            AreaRegistration.RegisterAllAreas();

            RegisterGlobalFilters(GlobalFilters.Filters);
            RegisterWebApi(GlobalConfiguration.Configuration);
            RegisterRoutes(RouteTable.Routes);
}

全局过滤器的方法:

public class CustomErrorHandler : HandleErrorAttribute {
        public override void OnException(ExceptionContext filterContext)
        {
            UIH.PACS.Common.Core.Logger.ErrorWithFormat("ex:{0}", filterContext.Exception);
            if (filterContext.Result is JsonResult)
            {
                //当结果为json时,设置异常已处理
                filterContext.ExceptionHandled = true;
            }
            else if (filterContext.Result is ActionResult)
            {
                RedirectResult r = new RedirectResult("~/Error");
                filterContext.ExceptionHandled = true;
                //r.ExecuteResult(filterContext);
                filterContext.Result = r;
                //RedirectToRouteResult r = new RedirectToRouteResult(
            }
            else
            {
                if (filterContext.HttpContext.Response.StatusCode == 404)
                {
                    RedirectResult r = new RedirectResult("~/Error");
                    r.ExecuteResult(filterContext);
                }
                //否则调用原始设置
                //base.OnException(filterContext);
            }
            //UrlHelper url = new UrlHelper(filterContext.RequestContext);
            //filterContext.HttpContext.Response.Redirect(url.Action("Index", "Error"));//跳转到新页面
            //base.OnException(filterContext);
        }
    }

自己写的过滤部分

//自定义的过滤器,过滤没有session的请求到登录界面
    public class CustomerFilterAttribute : ActionFilterAttribute
    {
        //
        // GET: /System/

        public override void OnActionExecuting(ActionExecutingContext filterContext)
        {
            //string controller = filterContext.RouteData.Values["Controller"].ToString();
            //string action = filterContext.RouteData.Values["Action"].ToString();
            string controller = filterContext.ActionDescriptor.ControllerDescriptor.ControllerName;
            string action = filterContext.ActionDescriptor.ActionName;
            if (controller == "LoginLogout" && action == "Login")
            {
                return;
            }
            else if (controller == "LoginLogout" && action == "validate")
            {
                return;
            }
            else if (controller == "LoginLogout" && action == "Logout")
            {
                return;
            }
            if (filterContext.HttpContext.Session.Count <= 0 || string.IsNullOrWhiteSpace(filterContext.HttpContext.Session["Valiable"].ToString()))
            { 
                //session已经超时则重新登录
                filterContext.Controller.TempData.Clear();
                RedirectResult r = new RedirectResult("~/LoginLogout/Login");
                filterContext.Result = r;
                return;
            }
            string valiable = string.Empty;
            valiable = filterContext.HttpContext.Session["Valiable"].ToString();
            if (string.Equals(valiable, "true")) {
                return;
            }
        }
    }

猜你喜欢

转载自blog.csdn.net/weixin_41556165/article/details/84643461
今日推荐