question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

"fetching resource list" issue

See original GitHub issue

I have configured Swashbuckle the same way I have done for other Web API websites, but this time I’m getting a message that says “fetching resource list: http://localhost:52302/swagger/docs/v1; Please wait” when I browse to http://localhost:52302/swagger/ui/index.

VERSION:

5.6.0 (Target Framework is “net46”)

STEPS TO REPRODUCE:

NuGet Packages

<?xml version="1.0" encoding="utf-8"?>
<packages>
  <package id="Autofac" version="3.5.2" targetFramework="net46" />
  <package id="Autofac.Configuration" version="3.3.0" targetFramework="net46" />
  <package id="Autofac.Owin" version="3.1.0" targetFramework="net46" />
  <package id="Autofac.Wcf" version="3.0.2" targetFramework="net46" />
  <package id="Autofac.WebApi2" version="3.4.0" targetFramework="net46" />
  <package id="Autofac.WebApi2.Owin" version="3.3.0" targetFramework="net46" />
  <package id="EntityFramework" version="6.1.3" targetFramework="net46" />
  <package id="FluentValidation" version="7.0.2" targetFramework="net46" />
  <package id="FluentValidation.WebApi" version="7.0.1" targetFramework="net46" />
  <package id="Hangfire" version="1.6.15" targetFramework="net46" />
  <package id="Hangfire.Autofac" version="2.3.1" targetFramework="net46" />
  <package id="Hangfire.Core" version="1.6.15" targetFramework="net46" />
  <package id="Hangfire.SqlServer" version="1.6.15" targetFramework="net46" />
  <package id="Microsoft.AspNet.Identity.Core" version="2.2.1" targetFramework="net46" />
  <package id="Microsoft.AspNet.Identity.EntityFramework" version="2.2.1" targetFramework="net46" />
  <package id="Microsoft.AspNet.Identity.Owin" version="2.2.1" targetFramework="net46" />
  <package id="Microsoft.AspNet.WebApi" version="5.2.3" targetFramework="net46" />
  <package id="Microsoft.AspNet.WebApi.Client" version="5.2.3" targetFramework="net46" />
  <package id="Microsoft.AspNet.WebApi.Core" version="5.2.3" targetFramework="net46" />
  <package id="Microsoft.AspNet.WebApi.Owin" version="5.2.3" targetFramework="net46" />
  <package id="Microsoft.AspNet.WebApi.WebHost" version="5.2.3" targetFramework="net46" />
  <package id="Microsoft.CodeDom.Providers.DotNetCompilerPlatform" version="1.0.4" targetFramework="net46" />
  <package id="Microsoft.Net.Compilers" version="2.2.0" targetFramework="net46" developmentDependency="true" />
  <package id="Microsoft.Owin" version="3.1.0" targetFramework="net46" />
  <package id="Microsoft.Owin.Host.SystemWeb" version="3.1.0" targetFramework="net46" />
  <package id="Microsoft.Owin.Security" version="3.1.0" targetFramework="net46" />
  <package id="Microsoft.Owin.Security.Cookies" version="3.1.0" targetFramework="net46" />
  <package id="Microsoft.Owin.Security.OAuth" version="3.1.0" targetFramework="net46" />
  <package id="Microsoft.Web.Infrastructure" version="1.0.0.0" targetFramework="net46" />
  <package id="Newtonsoft.Json" version="10.0.2" targetFramework="net46" />
  <package id="NLog" version="4.4.10" targetFramework="net46" />
  <package id="NLog.Config" version="4.4.10" targetFramework="net46" />
  <package id="NLog.Schema" version="4.4.10" targetFramework="net46" />
  <package id="Owin" version="1.0" targetFramework="net46" />
  <package id="Swashbuckle" version="5.6.0" targetFramework="net46" />
  <package id="Swashbuckle.Core" version="5.6.0" targetFramework="net46" />
  <package id="WebActivatorEx" version="2.0" targetFramework="net46" />
</packages>

Startup Class

[assembly: OwinStartup(typeof(MyNamespace.Startup))]

namespace MyNamespace
{
    public partial class Startup
    {
        public void Configuration(IAppBuilder app)
        {
            var container = GetContainer();

            GlobalConfiguration.Configuration.DependencyResolver = new AutofacWebApiDependencyResolver(container);
            GlobalConfiguration.Configure(WebApiConfig.Register);
            GlobalConfiguration.Configure(SwaggerConfig.Register);

            app.Use<ExceptionLoggingMiddleware>();
            app.UseAutofacMiddleware(container);
            app.UseAutofacWebApi(GlobalConfiguration.Configuration);

            ConfigureAuth(app);
            ConfigureHangfire(app, container);
        }
    }
}

Web API Config

    public static class WebApiConfig
    {
        public static void Register(HttpConfiguration config)
        {
            ConfigureRoutes(config);
            ConfigureToOnlyUseBearerTokenAuth(config);
            ConfigureMessageHandlers(config);
            ConfigureJsonFormatter(config);

            FluentValidationModelValidatorProvider.Configure(config);
        }

        private static void ConfigureRoutes(HttpConfiguration config)
        {
            config.MapHttpAttributeRoutes();

            config.Routes.MapHttpRoute(
                "DefaultApi",
                "{controller}/{id}",
                new { id = RouteParameter.Optional });
        }

        private static void ConfigureToOnlyUseBearerTokenAuth(HttpConfiguration config)
        {
            config.SuppressDefaultHostAuthentication();
            config.Filters.Add(new HostAuthenticationFilter(OAuthDefaults.AuthenticationType));
            config.Filters.Add(new ValidateModelStateFilter());
            config.Filters.Add(new SingleMemberSessionFilter());
        }

        private static void ConfigureMessageHandlers(HttpConfiguration config)
        {
            config.MessageHandlers.Add(new RequestResponseLoggingHandler());
            config.MessageHandlers.Add(new ResponseWrappingHandler());
            config.Services.Add(typeof(IExceptionLogger), new ExceptionLoggingHandler());
        }

        private static void ConfigureJsonFormatter(HttpConfiguration config)
        {
            config.Formatters.Add(new JsonMediaTypeFormatter());
            config.Formatters.JsonFormatter.Indent = true;

            // allow model with [serializable] attribute to work normally with web api
            ((DefaultContractResolver)config.Formatters.JsonFormatter.SerializerSettings.ContractResolver).IgnoreSerializableAttribute = true;

            FluentValidationModelValidatorProvider.Configure(config);
        }
    }

Swagger Config

    public static class SwaggerConfig
    {
        public static void Register(HttpConfiguration config)
        {
            if (config == null) throw new ArgumentNullException(nameof(config));

            config.EnableSwagger(i =>
            {
                i.SingleApiVersion("v1", "My API");
                i.IncludeXmlComments(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Docs.xml")); // XML file is outputed to the root directory of website (not bin) and included in csproj file as content
            })
            .EnableSwaggerUi();
        }
    }

All the controllers have all the appropriate attributes on the methods and their parameters e.g. route, HTTP Get/Post/Put, From URI/From Body.

All request and response classes simple and are not the same the database models used for Entity Framework.

EXPECTED RESULT:

The Swagger documentation is displayed

ACTUAL RESULT:

Documentation doesn’t load and the following message is displayed. fetching resource list: http://localhost:52302/swagger/docs/v1; Please wait.

ADDITIONAL INFO

The API works, it’s only the Swagger documentation that has an issue

Issue Analytics

  • State:closed
  • Created 6 years ago
  • Comments:13 (5 by maintainers)

github_iconTop GitHub Comments

2reactions
TheMagnificent11commented, Dec 21, 2017

I found the issue.

It’s our response handler. We don’t different HTTP results, it’s always 200 OK and the service response object has a success property and errors collection.

Response Handler

    public class ResponseWrappingHandler : DelegatingHandler
    {
        protected override async Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
        {
            var response = await base.SendAsync(request, cancellationToken);

            object content;
            HttpResponseMessage newResponse = null;

            if (response.Content is StreamContent)
            {
                // File download so just return
                return response;
            }

            if (response.TryGetContentValue(out content) && !response.IsSuccessStatusCode)
            {
                var error = content as HttpError;
                if (error?.ModelState != null)
                {
                    //Read as string
                    var httpErrorObject = await response.Content.ReadAsStringAsync();

                    //Convert to anonymous object
                    var anonymousErrorObject = new { message = "", ModelState = new Dictionary<string, string[]>() };

                    // Deserialize anonymous object
                    var deserializedErrorObject = JsonConvert.DeserializeAnonymousType(httpErrorObject, anonymousErrorObject);

                    // Get error messages from ModelState object
                    var modelStateErrors = deserializedErrorObject.ModelState
                        .Select(kvp => string.Join(". ", kvp.Value))
                        .ToList();

                    newResponse = request.CreateResponse(response.StatusCode, new ServiceResponse(modelStateErrors));
                }
                else
                {
                    return response;
                }
            }
            else if (content is ServiceResponse)
            {
                // Already is wrapped so don't worry about it
                return response;
            }

            if (newResponse == null)
            {
                newResponse = request.CreateResponse(response.StatusCode, new ServiceResponse<object>(content));
            }

            // Add Back the Response Headers
            foreach (var header in response.Headers) //Add back the response headers
            {
                newResponse.Headers.Add(header.Key, header.Value);
            }

            return newResponse;
        }
    }

Startup Web API Config

    public static class WebApiConfig
    {
        public static void Register(HttpConfiguration config)
        {
            ConfigureRoutes(config);
            ConfigureToOnlyUseBearerTokenAuth(config);
            ConfigureMessageHandlers(config);
            ConfigureJsonFormatter(config);

            FluentValidationModelValidatorProvider.Configure(config);
        }

        private static void ConfigureRoutes(HttpConfiguration config)
        {
            config.MapHttpAttributeRoutes();

            config.Routes.MapHttpRoute(
                "DefaultApi",
                "{controller}/{id}",
                new { id = RouteParameter.Optional });
        }

        private static void ConfigureToOnlyUseBearerTokenAuth(HttpConfiguration config)
        {
            config.SuppressDefaultHostAuthentication();
            config.Filters.Add(new HostAuthenticationFilter(OAuthDefaults.AuthenticationType));
            config.Filters.Add(new ValidateModelStateFilter());
            config.Filters.Add(new SingleMemberSessionFilter());
        }

        private static void ConfigureMessageHandlers(HttpConfiguration config)
        {
            config.MessageHandlers.Add(new RequestResponseLoggingHandler());

            // This line is the issue
            config.MessageHandlers.Add(new ResponseWrappingHandler());

            config.Services.Add(typeof(IExceptionLogger), new ExceptionLoggingHandler());
        }

        private static void ConfigureJsonFormatter(HttpConfiguration config)
        {
            config.Formatters.Add(new JsonMediaTypeFormatter());
            config.Formatters.JsonFormatter.Indent = true;

            // allow model with [serializable] attribute to work normally with web api
            ((DefaultContractResolver)config.Formatters.JsonFormatter.SerializerSettings.ContractResolver).IgnoreSerializableAttribute = true;

            FluentValidationModelValidatorProvider.Configure(config);
        }
    }

Any ideas on how to fix, other than removing it?

0reactions
Goddiewaynecommented, Nov 4, 2021

I had this issue as well, I had to troubleshoot each of my controllers by excluding them from the project thereby running them independently until I found the culprit. Somehow the [ResponseType(typeof())] of a particular controller action was the cause of the problem.

Read more comments on GitHub >

github_iconTop Results From Across the Web

Swagger UI hangs on "fetching resource list"
When I run the UI, it hangs on fetching resource list. I used chrome developer tools and I can see that the network...
Read more >
"fetching resource list" issue #1205
I get a message that says "fetching resource list: http://localhost:52302/swagger/docs/v1; Please wait". This is the same issue as this one: # ...
Read more >
Swagger UI Hangs on `Fetching resource list: Please wait`
I just forked the project and changed the buffer size and used the custom DLL while I'm waiting for a response on the...
Read more >
Fetching resource list: undefined; Please wait
Hello, I have got a problem with REST API, I'm sure to get the good JWT token, I tried both method, first with...
Read more >
Displaying REST API functions results in "fetching resource ...
Problem. Attempts to display REST API funcions of AppScan Enterprise using Internet Explorer version 9 result in message "fetching resource list: ...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found