1. 程式人生 > >MVC過濾器總結

MVC過濾器總結

註冊路由 

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;
            }
        }
    }