I have a fairly large ASP.NET WebApi (not ASP.NET Core!) that's been around for years and I'm trying to retrofit Swagger support onto it. The good news is that I've also got another, more recently developed, WebApi that is also not built on ASP.NET Core and has Swagger working on it just fine. Both projects had the same ProjectTypeGuids values in their *.csproj files and both projects target .Net v4.7.2. So, it seems like I should be able to lift all the Swagger-related NuGet packages and settings out of the second project and graft them into the first project to get the Swagger support I'm after.
Unfortunately, it hasn't turned out to be so simple. I seem to be running into problems with getting the routing to work out correctly, and I think that has to do with the fact that the first API is set up to be a web application on a web site, whereas the second API is set up to be the exclusive presence on a web server. More concretely, the URLs are https://www.some.host/FirstApi/controller/action/id for the first WebAPI and https://www.other.host/controller/action/id for the second WebAPI.
The code that is supposed to set all this up is spread out over several files as shown below, and reflects the pattern that works in the second WebApi.
Global.asax.cs
protected void Application_Start()
{
GlobalConfiguration.Configure(WebApiConfig.Register);
RouteConfig.RegisterRoutes(RouteTable.Routes);
Configure(GlobalConfiguration.Configuration).Wait();
}
WebApiConfig.cs
public static void Register(HttpConfiguration config)
{
// Formatter and filter setup
/* ... */
// Web API routes
config.MapHttpAttributeRoutes();
}
RouteConfig.cs
public class RouteConfig
{
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapHttpRoute(
name: "Default",
routeTemplate: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Get", id = UrlParameter.Optional });
}
}
Startup.cs
public partial class Startup
{
public void Configuration(IAppBuilder app)
{
app.UseCors(CorsOptions.AllowAll);
if (Settings.IsAzureEnvironment)
{
ConfigureAuth(app).Wait();
}
app.UseSwagger(typeof(WebApiApplication).Assembly).UseSwaggerUi3();
}
}
HomeController.cs
public class HomeController : ApiController
{
[Route(""), HttpGet]
[ApiExplorerSettings(IgnoreApi = true)]
public HttpResponseMessage RedirectToSwaggerUi()
{
var httpResponseMessage = new HttpResponseMessage(HttpStatusCode.Found);
httpResponseMessage.Headers.Location = new Uri("/FirstApi/swagger", UriKind.Relative);
return httpResponseMessage;
}
// Other methods like https://host/FirstApi/Home/Test that all work as expected
/* ... */
}
I've included a "FirstApi" segment in the Location URI while debugging locally (using a local installation of IIS) to account for the web app segment of the URL. With this, when I call https://localhost I get an error message like this
{
Message: "No HTTP resource was found that matches the request URI
'https://localhost/FirstApi/swagger/index.html?url=/FirstApi/swagger/v1/swagger.json'.",
MessageDetail: "No type was found that matches the controller named 'swagger'."
}
It's true that I do not have controller named "swagger" in my project, but I thought that the app.UseSwagger call in Startup.cs was supposed to put a handler in place that responds to requests that would otherwise get handled by a swagger controller. Is this not correct? Am I missing some configuration settings somewhere?