天天看點

WebApi過濾器

  1. 權限驗證過濾器
/// <summary>
/// 權限驗證過濾器
/// </summary>
public class AuthFilter : IAuthorizationFilter
{
    public void OnAuthorization(AuthorizationFilterContext context)
    {
        //if (context.Filters.Contains(new MyNoAuthentication()))
        //{
        //    return;
        //}
        var authorize = context.HttpContext.Request.Headers["token"];
        if (string.IsNullOrWhiteSpace(authorize))
        {
            context.Result = new JsonResult(new { code = 500, message = "token不能為空" });
            return;
        }
        //if (!MemoryCacheHelper.Exists(authorize))
        //{
        //    context.Result = new JsonResult("無效的授權資訊或授權資訊已過期");
        //    return;
        //}
    }
}
           
  1. 程式異常過濾器
/// <summary>
/// 程式異常過濾器
/// </summary>
public class ExceptionFilter : IAsyncExceptionFilter
{
    private readonly IWebHostEnvironment _environment;
    public ExceptionFilter(IWebHostEnvironment environment)
    {
        this._environment = environment;
    }

    public Task OnExceptionAsync(ExceptionContext context)
    {
        //context.Exception代表異常資訊對象
        //如果給 context.ExceptionHandled指派為true,則其他ExceptionFilter不會被執行
        //context.Result的值會被輸出到用戶端

        string msg;
        if (_environment.EnvironmentName == "Development")
        {
            msg = context.Exception.ToString();
        }
        else
        {
            msg = "伺服器發生未處理異常";
        }
        //可以加log 輸出
        JsonResult result = new JsonResult(new { code = 500, message = msg });
        context.Result = result;    //context.Result的值會被輸出到用戶端
        context.ExceptionHandled = true;  //其他ExceptionFilter不會被執行
        return Task.CompletedTask;
    }
}
           
  1. 模型驗證過濾器
/// <summary>
/// 模型驗證過濾器
/// </summary>
public class ModelValidateFilter : ActionFilterAttribute
{
    public override void OnActionExecuting(ActionExecutingContext context)
    {
        if (!context.ModelState.IsValid)
        {
            //擷取驗證失敗的模型字段
            var errors = context.ModelState
                .Where(e => e.Value.Errors.Count > 0)
                .Select(e => e.Value.Errors.First().ErrorMessage)
                .ToList();
            var str = string.Join("|", errors);
            //設定傳回内容
            JsonResult result = new JsonResult(new
            {
                Code = 10000,
                Msg = $"資料驗證:{str}"
            });
            context.Result = result;
        }
    }
}
           
  1. 限流過濾器
/// <summary>
/// 限流過濾器
/// </summary>
public class RateLimitFilter : IAsyncActionFilter
{
    private readonly IMemoryCache memCache;

    public RateLimitFilter(IMemoryCache memCache)
    {
        this.memCache = memCache;
    }

    public async Task OnActionExecutionAsync(ActionExecutingContext context, ActionExecutionDelegate next)
    {
        //Console.WriteLine("RateLimitActionFilter 執行action前");
        string ip = context.HttpContext.Connection.RemoteIpAddress.ToString();
        string cacheKey = $"lastvisittick_{ip}";
        long? lastVisit = memCache.Get<long?>(cacheKey);
        if (lastVisit == null || Environment.TickCount64 - lastVisit > 200) // Environment.TickCount64 系統時間
        {
            memCache.Set(cacheKey, Environment.TickCount64, TimeSpan.FromSeconds(10));//避免長期不通路的使用者,占據緩存的記憶體
            await next();
            //Console.WriteLine("RateLimitActionFilter 執行action後");
        }
        else
        {
            JsonResult result = new JsonResult(new
            {
                Code = 429,
                Msg = "您的,手速太快,通路太頻繁了!"
             });
            context.Result = result;
        }
    }
}