Search code examples
c#asp.net-core.net-coremiddlewareilogger

Calling log on custom middleware


I have a following custom middleware for error handling

public static class ErrorHandlerExtensions
{
    public static void UseErrorHandler(this IApplicationBuilder app)
    {
        app.UseExceptionHandler(appError =>
        {
            appError.Run(async context =>
            {
                var contextFeature = context.Features.Get<IExceptionHandlerFeature>();
                if (contextFeature == null) return;

                context.Response.Headers.Add("Access-Control-Allow-Origin", "*");
                context.Response.ContentType = "application/json";

                context.Response.StatusCode = contextFeature.Error switch
                {
                    BadRequestException => (int)HttpStatusCode.BadRequest,
                    OperationCanceledException => (int)HttpStatusCode.ServiceUnavailable,
                    NotFoundException => (int)HttpStatusCode.NotFound,
                    _ => (int)HttpStatusCode.InternalServerError
                };

                var errorResponse = new
                {
                    statusCode = context.Response.StatusCode,
                    message = contextFeature.Error.GetBaseException().Message
                };

                await context.Response.WriteAsync(JsonSerializer.Serialize(errorResponse));
            });
        });
    }
}

I want to add logger here as well. As we know since its a static class we can not declare readonly and pass it in constructor.

What I should do?

I tried to add logger like usual-

public static class ErrorHandlerExtension
{
    private static readonly ILogger _logger;
        public static void UseErrorHandler(this IApplicationBuilder app, ILogger logger)
{
logger= _logger;
}

But it's giving error as expected


Solution

  • I want to add logger here as well. As we know since its a static class we can not declare readonly and pass it in constructor.What I should do?

    You could get the required service by using the IApplicationBuilder.ApplicationServices.GetRequiredService method.

    More details, you could refer to below test codes:

    { app.UseExceptionHandler(appError => { appError.Run(async context => { var loggerFactory = app.ApplicationServices.GetRequiredService(); var _logger = loggerFactory.CreateLogger();

               _logger.LogError("test");
               var contextFeature = context.Features.Get<IExceptionHandlerFeature>();
               if (contextFeature == null) return;
    
               context.Response.Headers.Add("Access-Control-Allow-Origin", "*");
               context.Response.ContentType = "application/json";
    
               //context.Response.StatusCode = contextFeature.Error switch
               //{
               //    BadRequestException => (int)HttpStatusCode.BadRequest,
               //    OperationCanceledException => (int)HttpStatusCode.ServiceUnavailable,
               //    NotFoundException => (int)HttpStatusCode.NotFound,
               //    _ => (int)HttpStatusCode.InternalServerError
               //};
    
               var errorResponse = new
               {
                   statusCode = context.Response.StatusCode,
                   message = contextFeature.Error.GetBaseException().Message
               };
    
               await context.Response.WriteAsync(JsonSerializer.Serialize(errorResponse));
           });
       });
    

    Result:

    enter image description here