Using Swashbuckle.AspNetCore in Angular template project #126

Closed
opened 2025-08-09 17:15:06 +00:00 by fergalmoran · 0 comments
Owner

Originally created by @pha3l on 3/16/2018

I'm looking for a way to utilize the Swagger UI provided by this package in the angular starter. I've looked at the answer proposed in #1119 (which in turn references #973) and it seems things have changed a bit, as I have no call to MapSpaFallbackRoute in my Startup class. I am having the same issue described in these issues, in which the request to /swagger gets proxied to the SPA and thus ends up at a 404 error. I've tried moving the bits that enable the middleware above the call that enables mvc, not sure what else to do. Thanks for any help! Here's my Startup.cs if it helps at all:

    public class Startup
    {
        public Startup(IConfiguration configuration)
        {
            Configuration = configuration;
        }

        public IConfiguration Configuration { get; }

        // This method gets called by the runtime. Use this method to add services to the container.
        public void ConfigureServices(IServiceCollection services)
        {
            services.AddDbContext<ApplicationDbContext>(options =>
                {
                    options.UseNpgsql(Configuration.GetConnectionString("DefaultConnection"));
                }
            );
            
            services.AddIdentity<ApplicationUser, ApplicationRole>().AddEntityFrameworkStores<ApplicationDbContext>()
                .AddDefaultTokenProviders();
            
            services.AddAuthentication(opts =>
                {
                    opts.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
                    opts.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
                })
                .AddJwtBearer(options =>
                {
                    options.TokenValidationParameters = new TokenValidationParameters
                    {
                        ValidateIssuer = true,
                        ValidateAudience = true,
                        ValidateLifetime = true,
                        ClockSkew = TimeSpan.Zero,
                        ValidateIssuerSigningKey = true,
                        ValidIssuer = Configuration["Jwt:Issuer"],
                        ValidAudience = Configuration["Jwt:Issuer"],
                        IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(Configuration["Jwt:Key"]))
                    };
                });
            
            services.AddAuthorization(options =>
            {
                options.AddPolicy("TestPolicy", policy => policy.RequireClaim("testClaim", "potato"));
            });

            services.AddMvc().AddJsonOptions(options =>
            {
                options.SerializerSettings.ReferenceLoopHandling = ReferenceLoopHandling.Ignore;
            });

            services.AddCors();

            // Allow injection of configuration
            services.AddSingleton(Configuration);
            
            services.AddTransient<IUserService, ConsilioUserService>();
            services.AddTransient<ITimeService, ConsilioTimeService>();
            services.AddTransient<IHttpContextAccessor, HttpContextAccessor>();

            // In production, the Angular files will be served from this directory
            services.AddSpaStaticFiles(configuration => { configuration.RootPath = "ClientApp/dist"; });

            services.AddSwaggerGen(c => c.SwaggerDoc("v1", new Info {Title = "My API", Version = "v1"}));
        }

        // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
        public void Configure(IApplicationBuilder app, IHostingEnvironment env)
        {
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }
            else
            {
                app.UseExceptionHandler("/Home/Error");
            }

            app.UseStaticFiles();
            app.UseSpaStaticFiles();

            app.UseCors(builder =>
                builder.AllowAnyHeader().AllowAnyMethod().AllowAnyOrigin()
            );
            
            app.UseAuthentication();
            
            // Enable middleware to serve generated Swagger as a JSON endpoint.
            app.UseSwagger();

            // Enable middleware to serve swagger-ui (HTML, JS, CSS, etc.), specifying the Swagger JSON endpoint.
            app.UseSwaggerUI(c =>
            {
                c.SwaggerEndpoint("api/swagger/v1/swagger.json", "My API V1");
            });
            
            app.UseMvc(routes =>
            {
                routes.MapRoute(
                    name: "default",
                    template: "{controller}/{action=Index}/{id?}");
            });
            
            app.UseSpa(spa =>
            {
                spa.Options.SourcePath = "ClientApp";
                if (env.IsDevelopment())
                {
//                    spa.UseAngularCliServer(npmScript: "start");
                    spa.UseProxyToSpaDevelopmentServer("http://localhost:4200");
                }
            });
        }
*Originally created by @pha3l on 3/16/2018* I'm looking for a way to utilize the Swagger UI provided by this package in the angular starter. I've looked at the answer proposed in #1119 (which in turn references #973) and it seems things have changed a bit, as I have no call to `MapSpaFallbackRoute` in my Startup class. I am having the same issue described in these issues, in which the request to `/swagger` gets proxied to the SPA and thus ends up at a 404 error. I've tried moving the bits that enable the middleware above the call that enables mvc, not sure what else to do. Thanks for any help! Here's my `Startup.cs` if it helps at all: ```cs public class Startup { public Startup(IConfiguration configuration) { Configuration = configuration; } public IConfiguration Configuration { get; } // This method gets called by the runtime. Use this method to add services to the container. public void ConfigureServices(IServiceCollection services) { services.AddDbContext<ApplicationDbContext>(options => { options.UseNpgsql(Configuration.GetConnectionString("DefaultConnection")); } ); services.AddIdentity<ApplicationUser, ApplicationRole>().AddEntityFrameworkStores<ApplicationDbContext>() .AddDefaultTokenProviders(); services.AddAuthentication(opts => { opts.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme; opts.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme; }) .AddJwtBearer(options => { options.TokenValidationParameters = new TokenValidationParameters { ValidateIssuer = true, ValidateAudience = true, ValidateLifetime = true, ClockSkew = TimeSpan.Zero, ValidateIssuerSigningKey = true, ValidIssuer = Configuration["Jwt:Issuer"], ValidAudience = Configuration["Jwt:Issuer"], IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(Configuration["Jwt:Key"])) }; }); services.AddAuthorization(options => { options.AddPolicy("TestPolicy", policy => policy.RequireClaim("testClaim", "potato")); }); services.AddMvc().AddJsonOptions(options => { options.SerializerSettings.ReferenceLoopHandling = ReferenceLoopHandling.Ignore; }); services.AddCors(); // Allow injection of configuration services.AddSingleton(Configuration); services.AddTransient<IUserService, ConsilioUserService>(); services.AddTransient<ITimeService, ConsilioTimeService>(); services.AddTransient<IHttpContextAccessor, HttpContextAccessor>(); // In production, the Angular files will be served from this directory services.AddSpaStaticFiles(configuration => { configuration.RootPath = "ClientApp/dist"; }); services.AddSwaggerGen(c => c.SwaggerDoc("v1", new Info {Title = "My API", Version = "v1"})); } // This method gets called by the runtime. Use this method to configure the HTTP request pipeline. public void Configure(IApplicationBuilder app, IHostingEnvironment env) { if (env.IsDevelopment()) { app.UseDeveloperExceptionPage(); } else { app.UseExceptionHandler("/Home/Error"); } app.UseStaticFiles(); app.UseSpaStaticFiles(); app.UseCors(builder => builder.AllowAnyHeader().AllowAnyMethod().AllowAnyOrigin() ); app.UseAuthentication(); // Enable middleware to serve generated Swagger as a JSON endpoint. app.UseSwagger(); // Enable middleware to serve swagger-ui (HTML, JS, CSS, etc.), specifying the Swagger JSON endpoint. app.UseSwaggerUI(c => { c.SwaggerEndpoint("api/swagger/v1/swagger.json", "My API V1"); }); app.UseMvc(routes => { routes.MapRoute( name: "default", template: "{controller}/{action=Index}/{id?}"); }); app.UseSpa(spa => { spa.Options.SourcePath = "ClientApp"; if (env.IsDevelopment()) { // spa.UseAngularCliServer(npmScript: "start"); spa.UseProxyToSpaDevelopmentServer("http://localhost:4200"); } }); } ```
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: github/JavaScriptServices#126
No description provided.