swagger UI is not showing anything in webapi

16,003

Solution 1

Turns out this line:

config.DependencyResolver = new StructureMapDependencyResolver(container);

in the question's class XyzWebApiStructureMapContainerConfigurator caused some issues.

Hope this helps someone in the future.

Solution 2

Had the same issue. Turns out the DI (Unity in my case) was configured to bind all loaded assemblies (one of which is Swashbuckle.Core).

Just a bit of refining which assemblies get binded has solved the issue:

var assemblies = AppDomain.CurrentDomain.GetAssemblies().Where(asm => asm.FullName.StartsWith("MySolution.MyProject"));

// Web API configuration and services
var container = new UnityContainer();
container.RegisterTypes(
    AllClasses.FromAssemblies(assemblies),
    WithMappings.FromMatchingInterface,
    WithName.Default);

config.DependencyResolver = new UnityDependencyResolver(container);
Share:
16,003
cs0815
Author by

cs0815

Updated on July 18, 2022

Comments

  • cs0815
    cs0815 almost 2 years

    I followed this up to the xml doc part in order to create Swagger documentation using Swashbuckle. It should allow me to view the endpoints via (in my case):

    http://localhost:51854/swagger/ui/index

    Unfortunately, I cannot see any endpoints:

    enter image description here

    Any ideas why and how to fix this? Please note that I created my webapi from an empty webapi project - maybe that's the problem. Something must be missing but I am not sure what ...

    I have now identified the following code as the root cause. In Global.asax.cs:

    var container = new XyzWebApiStructureMapContainerConfigurator().Configure(GlobalConfiguration.Configuration);
    GlobalConfiguration.Configuration.Services
    .Replace(typeof(IHttpControllerActivator),
    new StructureMapHttpControllerActivator(container));
    

    Some classes:

    public class XyzWebApiStructureMapContainerConfigurator
    {
        public IContainer Configure(HttpConfiguration config)
        {
            var container = new Container(new BlaWebApiRegistry());
            config.DependencyResolver = new StructureMapDependencyResolver(container);
            return container;
        }
    }
    
    public class StructureMapDependencyResolver : StructureMapDependencyScope, IDependencyResolver, IHttpControllerActivator
    {
        private readonly IContainer _container;
    
        public StructureMapDependencyResolver(IContainer container)
            : base(container)
        {
            _container = container;
            container.Inject<IHttpControllerActivator>(this);
        }
    
        public IDependencyScope BeginScope()
        {
            return new StructureMapDependencyScope(_container.GetNestedContainer());
        }
    
        public IHttpController Create(
            HttpRequestMessage request,
            HttpControllerDescriptor controllerDescriptor,
            Type controllerType)
        {
            var scope = request.GetDependencyScope();
            return scope.GetService(controllerType) as IHttpController;
        }
    }
    

    PS:

    Simplified controller code:

    [RoutePrefix("api/XYZ")]
    public class BlaController : ApiController
    {
        private readonly ISomething _something;
    
        public BlaController(ISomething something)
        {
            _something = something;
        }
    
        [Route("")]
        [HttpGet]
        public IHttpActionResult Resources([FromUri] BlaRequest blaRequest)
        {
            // something exciting
            return Ok(returnObject);
        }
    }
    

    PPS:

    More code:

    // WebApiConfig

    public static void Register(HttpConfiguration config)
    {
        // Web API configuration and services  
    
        // Web API routes
        config.MapHttpAttributeRoutes();
    
        //var cors = new EnableCorsAttribute("*", "*", "*");
        config.EnableCors();
    
        config.Routes.MapHttpRoute(
        name: "DefaultApi",
        routeTemplate: "api/{controller}/{id}",
        defaults: new { id = RouteParameter.Optional }
        );
    }
    

    // Global.asax.cs

    public class WebApiApplication : System.Web.HttpApplication
    {
        protected void Application_Start()
        {
            GlobalConfiguration.Configure(WebApiConfig.Register);
    
            GlobalConfiguration.Configuration.Formatters.Clear();
            GlobalConfiguration.Configuration.Formatters.Add(new JsonMediaTypeFormatter());
    
            var container = new XyzWebApiStructureMapContainerConfigurator().Configure(GlobalConfiguration.Configuration);
            GlobalConfiguration.Configuration.Services
            .Replace(typeof(IHttpControllerActivator),
                new StructureMapHttpControllerActivator(container));
        }
    }
    

    PPPS:

    {
    swagger: "2.0",
    info: {
    version: "v1",
    title: "Bla.Di.Bla"
    },
    host: "localhost:51854",
    schemes: [
    "http"
    ],
    paths: { },
    definitions: { }
    }
    
    • strickt01
      strickt01 almost 8 years
      What are the names of your Controller classes? Sometimes this is just caused by not having the classes suffixed with "Controller". e.g. ProductController.cs etc. Other details of your endpoints such as whether the routing is set up using attribute routing or convention-based routing would also be helpful.
    • cs0815
      cs0815 almost 8 years
      @strickt01 - thanks. I added some controller sample code.
    • strickt01
      strickt01 almost 8 years
      Are you using OWIN? If so this might help.
    • Sampada
      Sampada almost 8 years
      what are your swagger.json contents that are obtained at localhost:51854/swagger/docs/v1 ?
    • cs0815
      cs0815 almost 8 years
      @strickt01 Owin is referenced but not sure if it is used. Our infrastructure expert had to make some adjustments to get things working in IIS for remote ajax requests. I have added more code. Please have a look at PPS.
    • cs0815
      cs0815 almost 8 years
      @Sampada - please see PPPS. Thanks.
    • Sampada
      Sampada almost 8 years
      Ok. This shows no APIs are being generated at the json level itself. My best guess here on why this is happening is lack of a basePath. Please try setting it in the swagger bean config.
    • cs0815
      cs0815 almost 8 years
      @Sampada - thanks. Bit confused now. This is Java stuff so would not apply in my .Net/Swashbuckle scenario.
    • Sampada
      Sampada almost 8 years
      Well, there should be a way to set the basePath in Swashbuckle as well. Agree that bean config is java stuff.
    • cs0815
      cs0815 almost 8 years
      I have identified the code in the Global.asax.cs as the root cause. see edited question.
    • Prasad Kanaparthi
      Prasad Kanaparthi about 5 years
      I'm facing same problem and after truns out above line swagger is working fine. But, DI was broken. Any alternative to above without comment?
  • Prasad Kanaparthi
    Prasad Kanaparthi about 5 years
    I'm facing same problem and after truns out above line swagger is working fine. But, DI was broken. Any alternative to above without comment?
  • ryanwebjackson
    ryanwebjackson about 4 years
    This doesn't seem like a solution. Is the issue that the SwaggerConfig is in the same namespace as the DI registration class?