Tom
Tom

Reputation: 8691

swagger : Failed to load API definition undefined /swagger/v1/swagger.json

I have tried to configure swagger in my asp.net core api and getting the following error. Failed to load API definition undefined /swagger/v1/swagger.json

I am not sure why I am getting this error. I have added the necessary configuration in the startup file

I have tried the following paths but there has been no difference

/swagger/v1/swagger.json
../swagger/v1/swagger.json
v1/swagger.json

startup.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.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2);


            services.AddSwaggerGen(c =>
            {

            });


            services.AddDbContext<NorthwindContext>(item => item.UseSqlServer(Configuration.GetConnectionString("NorthwindDBConnection")));
            services.AddCors(option => option.AddPolicy("MyPolicy", builder => {
                builder.AllowAnyOrigin().AllowAnyHeader().AllowAnyMethod();

            }));

            var mappingConfig = new MapperConfiguration(mc =>
            {
                mc.AddProfile(new MappingProfile());
            });

            IMapper mapper = mappingConfig.CreateMapper();
            services.AddSingleton(mapper);



            services.AddScoped<ICustomerRepository, CustomerRepository>();
        }

        // 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
            {
                // The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
                app.UseHsts();
            }
            app.UseCors("MyPolicy");
            app.UseHttpsRedirection();
            app.UseSwagger();
            app.UseSwaggerUI(c => { c.SwaggerEndpoint("/swagger/v1/swagger.json", "API name"); });
            app.UseMvc();
        }
    }

CustomerController

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Customer.Repository;
using CustomerService.Models;
using CustomerService.ViewModel;
using Microsoft.AspNetCore.Mvc;

namespace CustomerService.Controllers
{
    [Route("api/[controller]")]
    [ApiController]
    public class CustomersController : Controller
    {

        ICustomerRepository _customersRepository;


        public CustomersController(ICustomerRepository customersRepository)
        {
            _customersRepository = customersRepository;
        }

        [HttpGet]
        [Route("GetCustomers")]
        //[NoCache]
        [ProducesResponseType(typeof(List<CustomerViewModel>), 200)]
        [ProducesResponseType(typeof(ApiResponse), 400)]
        public async Task<IActionResult> Customers()
        {
            try
            {
                var customers = await _customersRepository.GetAllCustomers();
                if (customers == null)
                {
                    return NotFound();
                }

                return Ok(customers);
            }
            catch
            {
                return BadRequest();
            }
        }


        [HttpGet]
        [Route("GetCustomer")]
        //[NoCache]
        [ProducesResponseType(typeof(List<CustomerViewModel>), 200)]
        [ProducesResponseType(typeof(ApiResponse), 400)]
        public async Task<IActionResult> Customers(string customerId)
        {
            if (customerId == null)
            {
                return BadRequest();
            }

            try
            {
                var customer = await _customersRepository.GetCustomer(customerId);
                if (customer == null)
                {
                    return NotFound();
                }

                return Ok(customer);
            }
            catch
            {
                return BadRequest();
            }
        }

        [HttpPost]
        [Route("AddCustomer")]
        public async Task<IActionResult> AddCustomer([FromBody] CustomerViewModel model)
        {
            if (ModelState.IsValid)
            {
                try
                {
                    var customerId = await _customersRepository.Add(model);
                    if (customerId != null)
                    {
                        return Ok(customerId);
                    }
                    else
                    {
                        return NotFound();
                    }
                }
                catch(Exception ex)
                {
                    return BadRequest();
                }
            }
            return BadRequest();
        }


        [HttpPost]
        [Route("DeleteCustomer")]
        public async Task<IActionResult> DeleteCustomer(string customerId)
        {
            int result = 0;

            if (customerId == null)
            {
                return BadRequest();
            }

            try
            {
                var customer = await _customersRepository.Delete(customerId);
                if (customer == null)
                {
                    return NotFound();
                }

                return Ok(customer);
            }
            catch
            {
                return BadRequest();
            }
        }



        [HttpPost]
        [Route("UpdateCustomer")]
        public async Task<IActionResult> UpdateCustomer([FromBody] CustomerViewModel model)
        {
            if (ModelState.IsValid)
            {
                try
                {
                    await _customersRepository.Update(model);
                    return Ok();
                }
                catch(Exception ex)
                {
                    if (ex.GetType().FullName == "Microsoft.EntityFrameworkCore.DbUpdateConcurrencyException")
                    {
                        return NotFound();
                    }

                    return BadRequest();
                }
            }
            return BadRequest();
        }
    }



}

Upvotes: 6

Views: 22219

Answers (6)

Kay
Kay

Reputation: 350

If you want to access swagger via host:port/swagger/v1/swagger.json then you should add options: SwaggerGenOptions inside

public void ConfigureServices(IServiceCollection services)
{
    services.AddSwaggerGen(c => 
        c.SwaggerDoc("swagger/v1", new OpenApiInfo { Version = "1.0", Title = "API" });
    );
}

It should work properly.

Upvotes: 0

mvoelcker
mvoelcker

Reputation: 358

I know this was is resolved, but I had this same problem today.

In my case, the problem was that I had a base controller class I created to other controllers inherit from. The problem started to happen when I created a public function on the base class. Turning it to protected did the trick

Upvotes: 1

Todd Vance
Todd Vance

Reputation: 4711

If you are on the broken Swashbuckle page, Open Dev Tools ... look at the 500 response that Swagger sends back and you will get some great insight.

Here's the dumb thing I was doing ... had a route in the HTTPGet as well as a ROUTE route.

    [HttpGet("id")]
    [ProducesResponseType(typeof(string), 200)]
    [ProducesResponseType(500)]
    [Route("{employeeID:int}")]

enter image description here

Upvotes: 5

user2410689
user2410689

Reputation:

Swagger also cannot deal with two Classes having the same name (at least, not out of the box). So if you have two name spaces, and two classes having the same name, it will fail to initialize.

Upvotes: 4

Xueli Chen
Xueli Chen

Reputation: 12725

This is usually indicative of controllers/actions that Swashbuckle doesn't support for one reason or another.

It's expected that you don't have a swagger.json file in your project. Swashbuckle creates and serves that dynamically using ASP.NET Core's ApiExplorer APIs. What's probably happening here is that Swashbuckle is unable to generate Swagger.json and, therefore, the UI is failing to display.

It's hard to know exactly what caused the failure, so the best way to debug is probably just to remove half your controllers (just move the files to a temporary location) and check whether the issues persists. Then you'll know which half of your controllers contains the troublesome action. You can 'binary search' removing controllers (and then actions) until you figure out which action method is causing Swashbuckle to not be able to generate Swagger.json. Once you know that, it should be obvious whether this is some issue in your code or an issue that should be filed in the Swashbuckle repo.

You could press F12 to open the chrome browser's developer tools to check the cause of failure ,then enter the failed request path and click on the error file to preview the detailed error .

It could also be an issue with ambiguous routes or something like that tripping Swashbuckle up. Once you've narrowed down the cause of failure to something more specific like that, it can either be fixed or filed, as appropriate.

Upvotes: 1

Yigit Tanriverdi
Yigit Tanriverdi

Reputation: 964

You are getting an error. Because of you doubled your action names. Look at this example. Swagger – Failed To Load API Definition , Change [Route("GetCustomers")] names and try again.

Upvotes: 3

Related Questions