Exception filter in ASP.NET Core

Exception filters run when some of the exceptions are unhandled and thrown from an invoked action. The reason for the exception can be anything and so is the source of the exception. Exception filter provides the ability to handle the exceptions for all the controller methods at a single location. This is by creating a class, which inherits from the FilterAttribute and IExceptionFilter interface.

Here, the FilterAttribute class makes it possible to use the class as an attribute, and the IExceptionFilter interface contains the method named OnException. OnException is executed whenever any exception occurs in the controller action method.

Let's start by adding a new class named ExceptionLogFilter.cs. Now, derive this class from the ExceptionFilterAttribute and the IExceptionFilter. Implement the OnException method and add your custom logic to the method. But here I am saving that exception message in the log file. Hence, the code will look, as shown below.


using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Filters;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading.Tasks;

namespace ExceptionFilterWeb.Filter
{
    public class ExceptionLogFilter : ExceptionFilterAttribute, IExceptionFilter
    {
        public override void OnException(ExceptionContext context)
        {
            var exceptionMessage = context.Exception.Message;
            var stackTrace = context.Exception.StackTrace;
            var controllerName = context.RouteData.Values["controller"].ToString();
            var actionName = context.RouteData.Values["action"].ToString();
            var Message = "Date :" + DateTime.Now.ToString("dd-MM-yyyy hh:mm tt") + "Error Message:" + exceptionMessage + Environment.NewLine + "Stack Trace:" + stackTrace;
            //Save in a Log File
            StreamWriter log;
            FileStream fileStream = null;
            DirectoryInfo logDirInfo = null;
            FileInfo logFileInfo;

            string logFilePath = @"D:\aspnetcoreapi\Logs\";
            logFilePath = logFilePath + "Log-" + System.DateTime.Today.ToString("dd-MM-yyyy") + ".txt";
            logFileInfo = new FileInfo(logFilePath);
            logDirInfo = new DirectoryInfo(logFileInfo.DirectoryName);
            if (!logDirInfo.Exists)
                logDirInfo.Create();
            if(!logFileInfo.Exists)
            {
                fileStream = logFileInfo.Create();
            }
            else
            {
                fileStream = new FileStream(logFilePath, FileMode.Append);
            }
            log = new StreamWriter(fileStream);
            log.WriteLine("====================================================START=========================================================");

            log.WriteLine("Log Created At-" + DateTime.Now.ToString("dd-MM-yyyy hh:mm tt") + "Controller :"+controllerName+", Action :"+actionName+", Message :-" + Message);
            log.WriteLine("====================================================END=========================================================");
            log.Close();
            //Redirect To Error Page
            context.Result = new RedirectResult("/Error/Index");
            base.OnException(context);
        }
    }
}


Apply the class name as an attribute to the controller class. Add an exception in the controller Index method.

using ExceptionFilterWeb.Filter;
using ExceptionFilterWeb.Models;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Logging;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Threading.Tasks;

namespace ExceptionFilterWeb.Controllers
{
    //For all action methods 
    [ExceptionLogFilter]
    public class HomeController : Controller
    {
        private readonly ILogger<HomeController> _logger;
        
        
        public HomeController(ILogger<HomeController> logger)
        {
            _logger = logger;
        }
        //Here also we can assign Exception Filter Individually        
        public IActionResult Index()
        {
            int a = 10;
            int b = 0;
            int c = a / b;
            return View();
        }

        public IActionResult Privacy()
        {
            throw new Exception("Testing error");
            return View();
        }

    }
}

For Error, Create one ErrorController Page for Exception Handling...

using Microsoft.AspNetCore.Mvc;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;

namespace ExceptionFilterWeb.Controllers
{
    public class ErrorController : Controller
    {
        public IActionResult Index()
        {
            return View();
        }
    }
}

In Index.cshtml:

@{
    ViewData["Title"] = "Error Page";
}

<div class="text-center">
    <h1 class="display-4">Some Error Occured!!!</h1>
</div>

Output:




Post a Comment

0 Comments