NetCore過濾器
.netcore過濾器有以下幾種型別
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Filters;
using Microsoft.AspNetCore.Mvc.ModelBinding;
using Microsoft.AspNetCore.Mvc.ViewFeatures;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace NetCoreApp.Filters
{
//優先順序1:許可權過濾器:它在Filter Pipleline中首先執行,並用於決定當前使用者是否有請求許可權。如果沒有請求許可權直接返回。
public class MyAuthorization : IAuthorizationFilter
{
public void OnAuthorization(AuthorizationFilterContext context)
{
}
}
//優先順序2:資源過濾器: 它在Authorzation後面執行,同時在後面的其它過濾器完成後還會執行。Resource filters 實現快取或其它效能原因返回。因為它執行在模型繫結前,所以這裡的操作都會影響模型繫結。
public class MyResourceFilterAttribute : IResourceFilter
{
//這個ResourceFiltersAttribute是最適合做快取了,在這裡做快取有什麼好處?因為這個OnResourceExecuting是在控制器例項化之前運營,如果能再這裡獲取ViewReuslt就不必例項化控制器,在走一次檢視了,提升效能
private static readonly Dictionary<string, object> _Cache = new Dictionary<string, object>();
private string _cacheKey;
/// <summary>
/// 這個方法會在控制器例項化之前之前
/// </summary>
/// <param name="context"></param>
public void OnResourceExecuting(ResourceExecutingContext context)
{
_cacheKey = context.HttpContext.Request.Path.ToString();//這個是請求地址,它肯定是指向的檢視
if (_Cache.ContainsKey(_cacheKey))
{
var cachedValue = _Cache[_cacheKey] as ViewResult;
if (cachedValue != null)
{
context.Result = cachedValue;
}
}
}
/// <summary>
/// 這個方法是是Action的OnResultExecuted過濾器執行完之後在執行的(每次執行完Action之後得到就是一個ViewResult)
/// </summary>
/// <param name="context"></param>
public void OnResourceExecuted(ResourceExecutedContext context)
{
_cacheKey = context.HttpContext.Request.Path.ToString();//這個是請求地址
if (!string.IsNullOrEmpty(_cacheKey) && !_Cache.ContainsKey(_cacheKey))
{
//因為這個方法是是Action的OnResultExecuted過濾器執行完之後在執行的,所以context.Result必然有值了,這個值就是Action方法執行後得到的ViewResult
var result = context.Result as ViewResult;
if (result != null)
{
_Cache.Add(_cacheKey, result);
}
}
}
}
//優先順序3:方法過濾器:它會在執行Action方法前後被呼叫。這個可以在方法中用來處理傳遞引數和處理方法返回結果。
public class MyActionFilterAttribute : ActionFilterAttribute
{
public override void OnActionExecuting(ActionExecutingContext context)
{
//context.HttpContext.Response.WriteAsync("abc");
}
}
//優先順序4:異常過濾器:被應用全域性策略處理未處理的異常發生前異常被寫入響應體
public class MyExceptionFilterAttribute:ExceptionFilterAttribute
{
private readonly IModelMetadataProvider _moprovider;
public MyExceptionFilterAttribute(IModelMetadataProvider moprovider)
{
this._moprovider = moprovider;
}
public override void OnException(ExceptionContext context)
{
base.OnException(context);
if (!context.ExceptionHandled)//如果異常沒有被處理過
{
string controllerName = (string)context.RouteData.Values["controller"];
string actionName = (string)context.RouteData.Values["action"];
//string msgTemplate =string.Format( "在執行controller[{0}的{1}]方法時產生異常",controllerName,actionName);//寫入日誌
if (this.IsAjaxRequest(context.HttpContext.Request))
{
context.Result = new JsonResult(new
{
Result = false,
PromptMsg = "系統出現異常,請聯絡管理員",
DebugMessage = context.Exception.Message
});
}
else
{
var result = new ViewResult { ViewName = "~Views/Shared/Error.cshtml" };
result.ViewData = new ViewDataDictionary(_moprovider, context.ModelState);
result.ViewData.Add("Execption", context.Exception);
context.Result = result;
}
; }
}
//判斷是否為ajax請求
private bool IsAjaxRequest(HttpRequest request)
{
string header = request.Headers["X-Requested-With"];
return "XMLHttpRequest".Equals(header);
}
}
//優先順序5:結果過濾器:它可以在執行Action結果之前執行,且執行Action成功後執行,使用邏輯必須圍繞view或格式化執行結果。
public class MyResultFilterAttribute : ResultFilterAttribute
{
public override void OnResultExecuting(ResultExecutingContext context)
{
base.OnResultExecuting(context);
}
public override void OnResultExecuted(ResultExecutedContext context)
{
base.OnResultExecuted(context);
}
}
}
過濾器的全域性註冊
Startup.cs中
namespace NetCoreApp
{
public class Startup
{
public IConfiguration Configuration { get; } //建構函式注入:Configuration用於讀取配置檔案的
public Startup(IConfiguration configuration)
{
Configuration = configuration;
}
public void ConfigureServices(IServiceCollection services)
{
services.Configure<CookiePolicyOptions>(options =>
{
options.CheckConsentNeeded = context => true;
options.MinimumSameSitePolicy = SameSiteMode.None;
});
Action<MvcOptions> filters = new Action<MvcOptions>(r=> {
r.Filters.Add(typeof(MyAuthorization));
r.Filters.Add(typeof(MyExceptionFilterAttribute));
r.Filters.Add(typeof(MyResourceFilterAttribute));
r.Filters.Add(typeof(MyActionFilterAttribute));
r.Filters.Add(typeof(MyResultFilterAttribute));
});
services.AddMvc(filters) //註冊全域性過濾器
.SetCompatibilityVersion(CompatibilityVersion.Version_2_2);
services.AddAuthentication();
services.AddSession();
}
}
}
區域性註冊
我們建立了過濾器,除了註冊這個過濾器為全域性過濾器外,還可以在單個控制器,或者單個方法上使用過濾器
以控制器為列,平常我們直接在在控制器上打上我們的建立的過濾器的特性標籤就好了
[MyActionFilter] //在這裡打上你自己建立的過濾器名稱就好了
public class HomeController : Controller
{
private IUser _user { get; set; }
public HomeController(IUser user)//建構函式
{
this._user = user;
}
public IActionResult Index()
{
ViewBag.Now = DateTime.Now.ToString();
return View();
}
}
但是,如果你的過濾器中使用了,建構函式注入物件的形式,直接在控制器上打特性標籤就行不通了。(因為特性需要的引數必須是在這個特性構造前就已經寫好了的,不能依賴注入提供的)
例如:
public class MyActionFilterAttribute : ActionFilterAttribute
{
private ILogger<MyActionFilterAttribute> _logger;
public MyActionFilterAttribute(ILogger<MyActionFilterAttribute> logger)
{
this._logger = logger;
}
public override void OnActionExecuting(ActionExecutingContext context)
{
_logger.LogWarning("在這裡執行了Action方法");//記錄日誌
}
}
這時候我們就需要用另外一種形式對我們的過濾器進行註冊了
方式一:使用TypeFilter這種形式,
[TypeFilter(typeof(MyActionFilterAttribute))] 就表示這個MyActionFilterAttribute這個過濾器物件的建立交給DI來完成。
[TypeFilter(typeof(MyActionFilterAttribute))] //這時候需要這樣使用
public class HomeController : Controller
{
public IActionResult Index()
{
ViewBag.Now = DateTime.Now.ToString();
return View();
}
}
方式二:使用ServiceFilter這種形式
[ServiceFilter(typeof(MyActionFilterAttribute))]就表示這個MyActionFilterAttribute這個過濾器物件的建立交給DI來完成
但是這種方式需要多一個配置,就是需要在Startup.cs類中的ConfigureServices方法中新增一段配置程式碼
services.AddScoped(typeof(MyActionFilterAttribute));
這樣就可以在可控制器中使用ServiceFilter了
[ServiceFilter(typeof(MyActionFilterAttribute))]
public class HomeController : Controller
{
public IActionResult Index()
{
ViewBag.Now = DateTime.Now.ToString();
return View();
}
}
相關文章
- .NetCore——全域性異常過濾器ExceptionFilterAttributeNetCore過濾器ExceptionFilter
- 過濾器過濾器
- 4、過濾器的使用及自定義過濾器過濾器
- 點雲濾波器與過濾器過濾器
- CAN過濾器過濾器
- Filter過濾器Filter過濾器
- vue 過濾器Vue過濾器
- 代理過濾器過濾器
- Vue過濾器Vue過濾器
- DataV過濾器過濾器
- hbase過濾器過濾器
- Xor過濾器:比布隆Bloom過濾器更快,更小過濾器OOM
- Spring Cloud Gateway ---GatewayFilter過濾器、過濾器工廠(入門)SpringCloudGatewayFilter過濾器
- PHP 過濾器(Filter)PHP過濾器Filter
- vue---過濾器Vue過濾器
- Vue中過濾器Vue過濾器
- vue filters過濾器VueFilter過濾器
- 布隆過濾器過濾器
- SpringSecurity過濾器原理SpringGse過濾器
- 誠翔濾器光刻膠過濾器濾芯:保障光刻過程的高效與安全過濾器
- Spring Cloud Gateway中的過濾器工廠:重試過濾器SpringCloudGateway過濾器
- 監聽器和過濾器過濾器
- 跟我一起學.NetCore之MVC過濾器,這篇看完走路可以仰著頭走NetCoreMVC過濾器
- JavaWeb 中 Filter過濾器JavaWebFilter過濾器
- 5.scrapy過濾器過濾器
- 攔截過濾器模式過濾器模式
- Filter過濾器的使用Filter過濾器
- 13.gateway中的過濾器的介紹以及自定義過濾器Gateway過濾器
- Spring 過濾器和攔截器Spring過濾器
- 服務閘道器過濾器過濾器
- SpringBoot 攔截器、過濾器、監聽器Spring Boot過濾器
- Qt事件過濾器的使用QT事件過濾器
- vue 日期時間過濾器Vue過濾器
- 淺談布隆過濾器過濾器
- Wireshark的捕獲過濾器過濾器
- ASP.Net MVC過濾器ASP.NETMVC過濾器
- SpamSieve for mac(郵件過濾器)Mac過濾器
- Servlet過濾器原始碼分析Servlet過濾器原始碼