MVC過濾器總結
阿新 • • 發佈:2018-12-27
註冊路由
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;
}
}
}