'Some services are not able to be constructed (Error while validating the service descriptor 'ServiceType

P. G. Choudhury 146 Reputation points
2025-01-24T17:13:44.79+00:00

I am trying to implement global exception handling using custom middleware in a .NetCore webAPI project. My .NetCore version in 9. I am getting the above exception message when trying to implement it. Let me post the relevant code blocks so you can understand my approach and what I tried:

ExceptionMiddleware.cs -

public class ExceptionMiddleware
{
    private readonly RequestDelegate _next;
    private readonly ILogger _logger;

    public ExceptionMiddleware(RequestDelegate next, ILogger logger)
    {
        _logger = logger;
        _next = next;
    }

    public async Task InvokeAsync(HttpContext httpContext)
    {
        try
        {
            await _next(httpContext);
        }
        catch (Exception exp)
        {
            _logger.LogError($"An unhandled exception has occurred:{exp.GetBaseException}");

            await HandleExceptionAsync(httpContext, exp);
        }
    }

    private async Task HandleExceptionAsync(HttpContext httpContext, Exception exp)
    {
        httpContext.Response.StatusCode = (int)HttpStatusCode.InternalServerError;
        httpContext.Response.ContentType = "application/json";

        await httpContext.Response.WriteAsync(new ErrorDetails
        {
            StatusCode = httpContext.Response.StatusCode,
            Message = "Internal Server Error from Custom Middleware"
        }.ToString());
    }

My exception middleware extension class -

public static class ExceptionMiddlewareExceptions
{
    public static void ConfigureExceptionHandler(this WebApplication app, Microsoft.Extensions.Logging.ILogger logger)
    {
        app.UseExceptionHandler(appError =>
        {
            appError.Run(async context =>
            {
                context.Response.StatusCode = (int)HttpStatusCode.InternalServerError;
                context.Response.ContentType = "application/json";
                var contextFeature = context.Features.Get<IExceptionHandlerFeature>();
                if(contextFeature!=null)
                {
                    await context.Response.WriteAsync(new ErrorDetails
                    {
                        StatusCode = context.Response.StatusCode,
                        Message = "Backend Internal Server Error"
                    }.ToString());
                }
            });
        });
    }
    public static void ConfigureCustomExceptionMiddleware(this WebApplication app)
    {
        app.UseMiddleware<ExceptionMiddleware>();
    }
}

Code in Startup.cs -

builder.Services.AddSingleton<ExceptionMiddleware>();

var app = builder.Build();               <----    this line throws exception
var logger = app.Services.GetRequiredService<ExceptionMiddleware>();
app.ConfigureCustomExceptionMiddleware();

I have pointed out the line in Startup.cs where the exception is being thrown. Do I have to add a services.Transient, or services.AddSingleton somewhere in the Startup? I'm not sure.
Can you guide me on what exactly I am doing wrong in all of this? Copilot Chat proved to be of no help either. What do you recommend I change in all of this above code block?

Thanks

Developer technologies | ASP.NET | ASP.NET Core
0 comments No comments
{count} votes

2 answers

Sort by: Most helpful
  1. Anonymous
    2025-01-27T02:11:46.3433333+00:00

    Hi @P. G. Choudhury,The reason why you get the error when running the application for the var app = builder.Build(); is the Middleware should not be registered as a singleton, you should directly use it instead of register it.

    This is not a service.

    The second error for your codes is the incorrect logger injection, in your ExceptionMiddleware constructor, you are directly injecting ILogger. However, ILogger is a generic interface that is intended to be used as ILogger<T>, where T is typically the class type in which it’s being used.

    The third issue is you use the duplicate exception handling.You’re configuring both app.UseExceptionHandler and custom middleware (ExceptionMiddleware). They serve similar purposes but handle exceptions in different ways. Typically, you should choose one or the other.

    I suggest you could try modify your codes as below and then test again.

    1.Modify the ExceptionMiddleware to set the logger well.

        public class ExceptionMiddleware
        {
            private readonly RequestDelegate _next;
            private readonly ILogger<ExceptionMiddleware> _logger;
    
            public ExceptionMiddleware(RequestDelegate next, ILogger<ExceptionMiddleware> logger)
            {
                _logger = logger;
                _next = next;
            }
    
            public async Task InvokeAsync(HttpContext httpContext)
            {
                try
                {
                    await _next(httpContext);
                }
                catch (Exception exp)
                {
                    _logger.LogError($"An unhandled exception has occurred:{exp.GetBaseException}");
    
                    await HandleExceptionAsync(httpContext, exp);
                }
            }
    
            private async Task HandleExceptionAsync(HttpContext httpContext, Exception exp)
            {
                httpContext.Response.StatusCode = (int)HttpStatusCode.InternalServerError;
                httpContext.Response.ContentType = "application/json";
    
                await httpContext.Response.WriteAsync("test");
            }
        }
    
    

    2.Modify the ExceptionMiddlewareExtensions class as below:

        public static class ExceptionMiddlewareExtensions
        {
            public static void ConfigureCustomExceptionMiddleware(this WebApplication app)
            {
                app.UseMiddleware<ExceptionMiddleware>();
            }
        }
    
    

    3.Directly use it inside the program.cs:

    var builder = WebApplication.CreateBuilder(args);
    // Add services to the container.
    // Learn more about configuring OpenAPI at https://aka.ms/aspnet/openapi
    builder.Services.AddOpenApi();
    var app = builder.Build();
    // Configure the HTTP request pipeline.
    if (app.Environment.IsDevelopment())
    {
        app.MapOpenApi();
    }
    app.ConfigureCustomExceptionMiddleware(); // Use custom exception middleware here.
    app.UseHttpsRedirection();
    

    If the answer is the right solution, please click "Accept Answer" and kindly upvote it. If you have extra questions about this answer, please click "Comment".

     

    Note: Please follow the steps in our documentation to enable e-mail notifications if you want to receive the related email notification for this thread.

     

    0 comments No comments

  2. Raymond Huynh (WICLOUD CORPORATION) 620 Reputation points Microsoft External Staff
    2025-07-09T08:17:33.32+00:00

    Hello Choudhury,

    I checked out your code and the error you’re seeing. Here’s what’s up:

    You’re getting tripped up because you’re registering your ExceptionMiddleware as a singleton with AddSingleton<ExceptionMiddleware>(). Middleware in ASP.NET Core doesn’t need to be registered like a regular service. You just add it to the pipeline, and ASP.NET Core takes care of the rest.

    Also, in your middleware’s constructor, you’re injecting ILogger. It’s better to use ILogger<ExceptionMiddleware>, that way, your logs are nicely organized and easier to trace.

    And, just a heads up: you only need one global exception handler. If you’re using your custom middleware, you don’t need the built-in UseExceptionHandler as well.

    Here’s how you can tweak your code:

    1. Remove this line (you don’t need it):

    builder.Services.AddSingleton<ExceptionMiddleware>();
    

    2. Update your middleware constructor like this:

    public class ExceptionMiddleware
    {
        private readonly RequestDelegate _next;
        private readonly ILogger<ExceptionMiddleware> _logger;
     
        public ExceptionMiddleware(RequestDelegate next, ILogger<ExceptionMiddleware> logger)
        {
            _logger = logger;
            _next = next;
        }
     
        public async Task InvokeAsync(HttpContext httpContext)
        {
            try
            {
                await _next(httpContext);
            }
            catch (Exception exp)
            {
                _logger.LogError($"An unhandled exception has occurred: {exp.GetBaseException()}");
                await HandleExceptionAsync(httpContext, exp);
            }
        }
     
        private async Task HandleExceptionAsync(HttpContext httpContext, Exception exp)
        {
            httpContext.Response.StatusCode = (int)HttpStatusCode.InternalServerError;
            httpContext.Response.ContentType = "application/json";
            await httpContext.Response.WriteAsync(new ErrorDetails
            {
                StatusCode = httpContext.Response.StatusCode,
                Message = "Internal Server Error from Custom Middleware"
            }.ToString());
        }
    }
    

    3. Add your middleware to the pipeline like this (in Program.cs or Startup.cs):

    var builder = WebApplication.CreateBuilder(args);
    // ... other service registrations
     
    var app = builder.Build();
     
    // Just add your middleware here:
    app.UseMiddleware<ExceptionMiddleware>();
     
    // ... other middleware (like app.UseHttpsRedirection(), etc.)
    

    That’s it! No need to register the middleware as a service, just add it to the pipeline. And don’t forget to use the generic logger for better log messages.

    Hope that helps!


Your answer

Answers can be marked as Accepted Answers by the question author, which helps users to know the answer solved the author's problem.