Vy Do
Vy Do

Reputation: 52716

Blazor Swagger: Failed to load API definition. Fetch error: undefined /swagger/v1/swagger.json

I use .NET Core 3.1.200-preview-014977, Blazor, Swagger UI 5.0.0, my dependencies

enter image description here

I follow guide at https://learn.microsoft.com/en-us/aspnet/core/tutorials/getting-started-with-swashbuckle?view=aspnetcore-3.1&tabs=visual-studio . This is my config

using foo.Areas.Identity;
using foo.Controllers;
using foo.Data;
using Demo.Blazor;
using DevExpress.Blazor.DocumentMetadata;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Components.Authorization;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Identity;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Options;
using System.Globalization;
using System.Net.Http;
using Microsoft.OpenApi.Models;
using System;

namespace foo
{

    public class Startup
    {

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

        public IConfiguration Configuration { get; }

        public void ConfigureServices(IServiceCollection services)
        {
            CultureInfo.DefaultThreadCurrentCulture = new CultureInfo("vi-VN");
            services.AddServerSideBlazor().AddCircuitOptions(options => { options.DetailedErrors = true; });
            services.AddDbContext<ApplicationDbContext>(options => options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection")));
            services.AddDefaultIdentity<IdentityUser>().AddRoles<IdentityRole>().AddEntityFrameworkStores<ApplicationDbContext>();          
            services.AddRazorPages().AddJsonOptions(options => options.JsonSerializerOptions.PropertyNamingPolicy = null);
            services.AddRazorPages().AddRazorPagesOptions(options =>
            {
                //options.Conventions.AuthorizePage("/currencies");
                //options.Conventions.AuthorizeFolder("/accounts");  
            });
            services.AddServerSideBlazor();
            services.AddScoped<AuthenticationStateProvider, RevalidatingIdentityAuthenticationStateProvider<IdentityUser>>();
            services.AddSingleton<WeatherForecastService>();
            services.AddDocumentMetadata((serviceProvider, registrator) =>
            {
                DemoConfiguration config = serviceProvider.GetService<IOptions<DemoConfiguration>>().Value;
                config.RegisterPagesMetadata(registrator);
            });
            services.AddMvc();
            services.AddHealthChecks();
            services.AddHttpClient();
            services.AddScoped<HttpClient>((sp) => {
                var httpClient = sp.GetService<IHttpClientFactory>().CreateClient();
                httpClient.DefaultRequestHeaders.Add("Accept", "application/json");
                return httpClient;
            });
            services.AddDevExpressBlazor();
            services.AddControllers();
            services.AddSwaggerGen(c =>
            {
                c.SwaggerDoc("v1", new OpenApiInfo { Title = "My API", Version = "v1" });
            });
        }

        public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
        {
            // 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("/swagger/v1/swagger.json", "My API V1");
            });

            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
                app.UseDatabaseErrorPage();
            }
            else
            {
                app.UseExceptionHandler("/Error");
                app.UseHsts();
            }
            app.UseHttpsRedirection();
            app.UseStaticFiles();           
            app.UseRouting();
            app.UseAuthentication();
            //app.UseAuthorization();
            app.UseEndpoints(endpoints =>
            {
                endpoints.MapControllers();
                endpoints.MapRazorPages();
                endpoints.MapBlazorHub();
                endpoints.MapFallbackToPage("/_Host");
                endpoints.MapHealthChecks("/health");
            });
        }
    }

}

I catch error:

Failed to load API definition.

enter image description here

How to fix it?

Upvotes: 1

Views: 1523

Answers (2)

Navus
Navus

Reputation: 109

The issue may occur if one of your controller's is missing [Http*] attributes. Consider the code below:

    [Route("[action]")]
    public async Task<IEnumerable<IdentityRole>> GetRoles()
    {
        _logger.LogDebug("Getting roles");
        return await _roleManager.Roles.ToListAsync();
    }

Your application will work, but Swagger wouldn't. Only because the example endpoint does not have [Http*] attribute defined, and thus, the swagger would fail to 'parse' your controller. Hence you see "Failed to load API definition." error message.

In this case, you would add [HttpGet] attribute like so:

    [HttpGet]
    [Route("[action]")]
    public async Task<IEnumerable<IdentityRole>> GetRoles()
    {
        _logger.LogDebug("Getting roles");
        return await _roleManager.Roles.ToListAsync();
    }

Hope this help! This may not be an exact issue you are having, but the point is that if your controller's are not defined using common patterns, swagger will not be able to recognize them.

Good luck!

Upvotes: 2

OIbuoye
OIbuoye

Reputation: 309

It should be like this

        app.UseSwaggerUI(c =>
       {
           c.SwaggerEndpoint("v1/swagger.json", "My API V1");
       });

Upvotes: 1

Related Questions