IApiExplorer Support in Orchard

Topics: Core, General
May 4, 2015 at 5:08 AM
Hi all,

I'm trying to use Swagger/Swashbuckle with Orchard CMS to add automatic Web API documentation to my website.

However Orchard doesn't seem to support this due to the ApiExplorer class using HostedHttpRouteCollection to get the list of routes which won't return anything as it checks if they are of type HttpWebRoute as can be seen here. They are of type ShellRoute instead.

You can see this in Global.asax if you check GlobalConfiguration.Configuration.Routes, it will have a number of _routeCollection entries but none are returned on enumeration.

So I was wondering if someone has experience with getting ApiExplorer working or can confirm if this isn't currently supported?
May 7, 2015 at 3:08 AM
Edited May 7, 2015 at 3:09 AM
I managed to solve this one by duplicating the routes at the end of the RouteTable and copying them as HttpRoute instead of ShellRoute..
    public class SwashbuckleStartup : IFrameworkShellEvents
    {
        public void Activated()
        {
            // Add WebApi routes as standard HttpRoutes instead of ShellRoutes so that ApiExplorer can discover them.
            var httpRoutes = GetHttpRoutes(RouteTable.Routes);
            CopyHttpRoutes(RouteTable.Routes, httpRoutes);

            // The WebHostAssembliesResolver uses BuildManager.GetReferencedAssemblies() which won't work when loading assemblies into the AppDomain at runtime.
            GlobalConfiguration.Configuration.Services.Replace(typeof(IAssembliesResolver), new DefaultAssembliesResolver());

            // Initialize Swashbuckle / ApiExplorer
            SwaggerConfig.Register();
        }

        private IEnumerable<RouteBase> GetHttpRoutes(IEnumerable<RouteBase> routes)
        {
            var httpRoutes = new List<RouteBase>();
            foreach (var route in routes)
            {
                var shellRoute = route as ShellRoute;
                if (shellRoute == null || !shellRoute.IsHttpRoute) continue;

                httpRoutes.Add(shellRoute.Route);
            }

            return httpRoutes;
        }

        private void CopyHttpRoutes(RouteCollection routes, IEnumerable<RouteBase> httpRoutes)
        {          
            using (routes.GetWriteLock())
            {
                foreach (var httpRoute in httpRoutes)
                {
                    routes.Add(httpRoute);
                }
            }
        }

        public void Terminating() {}
    }
Developer
May 7, 2015 at 1:12 PM
Where did you get IFrameworkShellEvents?