ASP.NET Core 8 Web API with Swagger not running as localhost web app

85 views Asked by At

I'm trying to created an ASP.NET Core 8 Web API using only CLI and have the program.cs as shown below.

When I run this from VS 2022, no compiler or runtime errors are appearing.

But when this is run from a "docker-compose up" I dot get specific error:

2024-03-28 17:54:11 Unhandled exception. System.InvalidOperationException: Unable to find the required services. Please add all the required services by calling 'IServiceCollection.AddAuthorization' in the application startup code.

2024-03-28 17:54:11 at Microsoft.AspNetCore.Builder.AuthorizationAppBuilderExtensions.VerifyServicesRegistered(IApplicationBuilder app)
2024-03-28 17:54:11 at Microsoft.AspNetCore.Builder.AuthorizationAppBuilderExtensions.UseAuthorization(IApplicationBuilder app)
2024-03-28 17:54:11 at WebApi.Program.Main(String[] args) in /app/Program.cs:line 41

Code:

using Microsoft.EntityFrameworkCore;

namespace WebApi
{
    public class Program
    {
        public static void Main(string[] args)
        {
            var builder = WebApplication.CreateBuilder(args);
            var services = builder.Services;

            services.AddEndpointsApiExplorer();
            services.AddSwaggerGen();

            services.AddControllers();

            /*
            Console.WriteLine("Preparing DbContext");
            services.AddDbContext<ParkingDbContext>(options =>
                options.UseNpgsql(builder.Configuration.GetConnectionString("DefaultConnection")));
            */

            services.AddAuthorization(); // Move AddAuthorization here

            services.AddHealthChecks();

            var app = builder.Build();

            app.UseAuthorization();

            if (app.Environment.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
                app.UseSwagger();
                app.UseSwaggerUI();
            }

            // Configure the HTTP request pipeline.
            app.UseRouting();
            
            app.MapControllers();

            app.Run();
        }
    }
}

As you notice I do have the .AddAuthorization method above but when run and opening a browser localhost is not running.

I'm probably missing something very obvious here, have spent some hours searching here without any luck.

2

There are 2 answers

10
Md Farid Uddin Kiron On BEST ANSWER

But when this is run from a "docker-compose up" I dot get specific error.

According to your shared code snippet, you are having the right exception. Though, you have added the app.UseAuthorization() however, the middleware order has not been followed. Consequently, it has thrown that error.

In order to inject middleware order correctly, app.UseAuthorization() should be called after app.UseRouting() in middleware pipeline. This is essential for the authorization middleware to process requests after routes have been matched.

Correct order would be:

enter image description here

app.UseRouting();

app.UseAuthentication();
app.UseAuthorization();
app.MapControllers();

app.Run();

Note: Above order should resolve your error. In addition, please refer to this official document.

0
Mauricio Gracia Gutierrez On

So not only the order of the middleware was incorrect but there were a couple of things missing in the swagger configuration

the RoutePrefix is set to empty so that opening localhost:5000/ will show the swagger page, otherwise localhost:5000/swagger should be used

using Microsoft.EntityFrameworkCore;
using Microsoft.OpenApi.Models;

namespace WebApi
{
    public class Program
    {
        public static void Main(string[] args)
        {
            var builder = WebApplication.CreateBuilder(args);
            var services = builder.Services;

            // Add DbContext
            services.AddDbContext<ParkingDbContext>(options =>
                options.UseNpgsql(builder.Configuration.GetConnectionString("DefaultConnection")));

            // Add Swagger services
            services.AddEndpointsApiExplorer();
            services.AddSwaggerGen(c =>
            {
                c.SwaggerDoc("v1", new OpenApiInfo { Title = "My API", Version = "v1" });
            });

            // Add controllers
            services.AddControllers();

            var app = builder.Build();

            if (app.Environment.IsDevelopment())
            {
                // Enable Swagger UI
                app.UseDeveloperExceptionPage();
                app.UseSwagger();
                app.UseSwaggerUI(c =>
                {
                    c.SwaggerEndpoint("/swagger/v1/swagger.json", "My API V1");
                    c.RoutePrefix = "";
                });
            }

            // Enable endpoint routing
            app.UseRouting();

            // Configure authentication and authorization
            app.UseAuthentication();
            app.UseAuthorization();

            // Map controllers
            app.MapControllers();

            app.Run();
        }
    }
}