If I host my WebApi on an HTTP server on port 80, but that server is a behind a proxy on port 8080 for example, the SwaggerUi fails to load.
This happens because the client settings are setup by the server part, and not on the client part (javascript). Swagger tries to load the api-docs hosted on port 80, but from the client's perspective, the server is running on port 8080.
I stumbled across this issue when I started deploying my Api's on Azure as cloud-services. Internally, they are hosted on IIS on port 80, but externally, they are forwarded through another port...
I was forced to inject javascript with some messy code in order to rewrite the url properly.
I think you may be able to solve this in a cleaner way with the config setting - ResolveBasePathUsing. With this, you can write your own custom code to resolve the external URL from the incoming HttpRequestMessage. If you know this in advance you could just hard-code it or better still you may be able to infer it from custom HTTP headers set by the proxy.
See the readme for a description https://github.com/domaindrivendev/Swashbuckle#resolvebasepathusing and let me know if this works
Cheers
Thanks for your reply :)
I've already tried using the ResolveBasePathUsing. It is a valid solution, if you only access to the api via the proxy. Which is not the case; plus, it only allows me to setup the base path (host+port+base) and not the entire url.
Please note that when you host things on azure, the public url is completly different from the internal one (public is something like: http://app.cloudapp.net:1234/path, and internally is something like: http://machine-name:80/path).
This is my infrastructure: I have clients that only can access through the proxy, and I have other (trusted) clients that access through the intranet.
Internet ----- proxy port 8080 ---- WebApi on port 80
Intranet ------------------------------- WebApi on port 80
As you can see, the API must be available through the port 80 and 8080 (which is rewriten by the proxy). Because of this, the server cannot be part of the url setup process as it only know the port where the webserver is hosting the app.
Update:
I followed your suggestion and used ResolveBasePathUsing and read the HOST header to build the basePath. I was able to browse the operations page successfully.
This is the code i used to setup the basePath:
c.ResolveBasePathUsing(
(request) =>
{
//return "http://petstore.swagger.wordnik.com/api/api-docs#";
var host = request.Headers.Host;
string vdir = request.RequestUri.AbsolutePath.Replace("/swagger/ui/index.html", "");
string baseUrl = string.Format("{0}://{1}{2}", request.RequestUri.Scheme, host, vdir);
return baseUrl;
});
Now have a new problem. When use the TryOut button on the operation page, it fails to resolve the proper api url. Swagger is issuing the test request to the following url:
http://myapp.test.net:16013/CarApp/swagger/api-docs/Cars/api/Cars
(the fragment /swagger/api-docs/Cars should not be here)
The correct url should be: http://myapp.test.net:16013/CarApp/api/Cars
Update 2:
The problem above only happens when you try to override the BaseUrl using the method you suggested. If I dont use any customized baseUrl, everything works fine...but again, not behind a proxy..
Could you take a look into that?
You just need to tweak your implementation. Replace ...
string vdir = request.RequestUri.AbsolutePath.Replace("/swagger/ui/index.html", "");
With this ...
string vdir = request.GetConfiguration().VirtualPathRoot.TrimEnd('/');
The basePathResolver is used during UI requests (/swagger/ui) and doc requests (/swagger/api-docs") . Your implementation doesn't address the latter case and this is why the wrong basePath is being returned with the Swagger doc, hence affecting the TryOut action.
Thank you a lot :)
I can confirm the following solution works perfectly!
Could you add this to the documentation page? It will surely help a ton of people out there :)
Most helpful comment
You just need to tweak your implementation. Replace ...
With this ...
The basePathResolver is used during UI requests (/swagger/ui) and doc requests (/swagger/api-docs") . Your implementation doesn't address the latter case and this is why the wrong basePath is being returned with the Swagger doc, hence affecting the TryOut action.