asp.net core3.1実戦開発(Filterの使用)


.net core異常フィルタの使用


まずコードは次のとおりです.
public class CustomExceptionFilterAttribute : ExceptionFilterAttribute
{
    #region Identity
    private readonly ILogger<CustomExceptionFilterAttribute> _logger;
    private readonly IModelMetadataProvider _modelMetadataProvider;
    public CustomExceptionFilterAttribute(ILogger<CustomExceptionFilterAttribute> logger
        , IModelMetadataProvider modelMetadataProvider)
    {
        this._modelMetadataProvider = modelMetadataProvider;
        this._logger = logger;
    }
    #endregion
    /// 
    ///     ,       
    ///         
    /// 
    /// 
    public override void OnException(ExceptionContext context)
    {
        if (!context.ExceptionHandled)
        {
            this._logger.LogError($"{context.HttpContext.Request.RouteValues["controller"]} is Error");
            if (this.IsAjaxRequest(context.HttpContext.Request))//header     XMLHttpRequest
            {
                context.Result = new JsonResult(new
                {
                    Result = false,
                    Msg = context.Exception.Message
                });//   ---        ,    Action
            }
            else
            {
                var result = new ViewResult { ViewName = "~/Views/Shared/Error.cshtml" };
                result.ViewData = new ViewDataDictionary(_modelMetadataProvider, context.ModelState);
                result.ViewData.Add("Exception", context.Exception);
                context.Result = result;
            }
            context.ExceptionHandled = true;
        }
    }
    private bool IsAjaxRequest(HttpRequest request)
    {
        string header = request.Headers["X-Requested-With"];
        return "XMLHttpRequest".Equals(header);
    }
}

第1の使用方法

[ServiceFilter(typeof(CustomExceptionFilterAttribute))]
public IActionResult Index()
{
    return View();
}
 public void ConfigureServices(IServiceCollection services)
{
    services.AddScoped(typeof(CustomExceptionFilterAttribute));//    new                 
}

第2の使用方法

[TypeFilter(typeof(CustomExceptionFilterAttribute))]
public IActionResult Index()
{
    return View();
}

第3の使用方法


カスタムインプリメンテーション
 /// 
    ///     Filter     
    /// 
    public class CustomIOCFilterFactoryAttribute : Attribute, IFilterFactory
    {
        private readonly Type _FilterType = null;

        public CustomIOCFilterFactoryAttribute(Type type)
        {
            this._FilterType = type;
        }
        public bool IsReusable => true;

        public IFilterMetadata CreateInstance(IServiceProvider serviceProvider)
        {
            //return (IFilterMetadata)serviceProvider.GetService(typeof(CustomExceptionFilterAttribute));

            return (IFilterMetadata)serviceProvider.GetService(this._FilterType);
        }
    }

使用

[CustomIOCFilterFactoryAttribute(typeof(CustomExceptionFilterAttribute))]/
public IActionResult Index()
{
    return View();
}

.net core動作フィルタの使用

public class CustomActionFilterAttribute : ActionFilterAttribute
    {
        public override void OnActionExecuted(ActionExecutedContext context)
        {
        //       (    ,     ),           
        context.HttpContext.Response.Headers.Add("Cache-Control", "public,max-age=6000");
            Console.WriteLine($"This {nameof(CustomActionFilterAttribute)} OnActionExecuted{this.Order}");
        }
        public override void OnActionExecuting(ActionExecutingContext context)
        {
            Console.WriteLine($"This {nameof(CustomActionFilterAttribute)} OnActionExecuting{this.Order}");
        }
        public override void OnResultExecuting(ResultExecutingContext context)
        {
            Console.WriteLine($"This {nameof(CustomActionFilterAttribute)} OnResultExecuting{this.Order}");
        }
        public override void OnResultExecuted(ResultExecutedContext context)
        {
            Console.WriteLine($"This {nameof(CustomActionFilterAttribute)} OnResultExecuted{this.Order}");
        }
    }

    public class CustomControllerFilterAttribute : ActionFilterAttribute
    {
        public override void OnActionExecuted(ActionExecutedContext context)
        {
            Console.WriteLine($"This {nameof(CustomControllerFilterAttribute)} OnActionExecuted {this.Order}");
        }
        public override void OnActionExecuting(ActionExecutingContext context)
        {
            Console.WriteLine($"This {nameof(CustomControllerFilterAttribute)} OnActionExecuting{this.Order}");
        }
        public override void OnResultExecuting(ResultExecutingContext context)
        {
            Console.WriteLine($"This {nameof(CustomControllerFilterAttribute)} OnResultExecuting{this.Order}");
        }
        public override void OnResultExecuted(ResultExecutedContext context)
        {
            Console.WriteLine($"This {nameof(CustomControllerFilterAttribute)} OnResultExecuted{this.Order}");
        }
    }

    public class CustomGlobalFilterAttribute : ActionFilterAttribute
    {
        public override void OnActionExecuted(ActionExecutedContext context)
        {
            Console.WriteLine($"This {nameof(CustomGlobalFilterAttribute)} OnActionExecuted{this.Order}");
        }
        public override void OnActionExecuting(ActionExecutingContext context)
        {
            Console.WriteLine($"This {nameof(CustomGlobalFilterAttribute)} OnActionExecuting{this.Order}");
        }
        public override void OnResultExecuting(ResultExecutingContext context)
        {
            Console.WriteLine($"This {nameof(CustomGlobalFilterAttribute)} OnResultExecuting{this.Order}");
        }
        public override void OnResultExecuted(ResultExecutedContext context)
        {
            Console.WriteLine($"This {nameof(CustomGlobalFilterAttribute)} OnResultExecuted{this.Order}");
        }
    }
/// 
///   ---   ---Action  Order  0,            
 /// 
 /// 
 [CustomActionFilterAttribute(Order = 10)]
 [CustomActionFilterAttribute]
 [CustomActionCacheFilterAttribute(Order = -1)]
 public IActionResult Info()
 {
     Console.WriteLine($"This is {nameof(ThirdController)} Info");

     base.ViewBag.Now = DateTime.Now;
     Thread.Sleep(2000);
     return View();
 }

.net core Resourceフィルタの使用(動作が直接ビューに戻るのを避ける)

// 
    /// 
    /// 
    public class CustomResourceFilterAttribute : Attribute, IResourceFilter, IFilterMetadata
    {
        private static Dictionary<string, IActionResult> CustomCache = new Dictionary<string, IActionResult>();
        /// 
        ///          
        /// 
        /// 
        public void OnResourceExecuting(ResourceExecutingContext context)
        {
            Console.WriteLine($"This is {nameof(CustomResourceFilterAttribute) }OnResourceExecuting");
            //if    ,      
            string key = context.HttpContext.Request.Path;
            if (CustomCache.ContainsKey(key))
            {
                context.Result = CustomCache[key];//   -- Result   ,  Result      Html
            }
        }
        /// 
        ///          
        /// 
        /// 
        public void OnResourceExecuted(ResourceExecutedContext context)
        {
            Console.WriteLine($"This is {nameof(CustomResourceFilterAttribute) }OnResourceExecuted");
            //        
            string key = context.HttpContext.Request.Path;
            if (!CustomCache.ContainsKey(key))
            {
                CustomCache.Add(key, context.Result);
            }
        }
    }
[CustomResourceFilterAttribute]//     
 public IActionResult Info()
 {
     Console.WriteLine($"This is {nameof(ThirdController)} Info");

     base.ViewBag.Now = DateTime.Now;
     Thread.Sleep(2000);
     return View();
 }

グローバル有効化

public void ConfigureServices(IServiceCollection services)
        {
            services.AddSession();
            services.AddControllersWithViews(
                options =>
                {
                    options.Filters.Add<CustomExceptionFilterAttribute>();//    
                    options.Filters.Add<CustomGlobalFilterAttribute>();
                });
        }