Swashbuckle.WebApi icon indicating copy to clipboard operation
Swashbuckle.WebApi copied to clipboard

Swagger navigates to wrong UI URL when using Virtual directory in Owin enabled asp.net

Open pjc2007 opened this issue 6 years ago • 10 comments

VERSION:

Provide the version of Swashbuckle you're using

<package id="Swashbuckle" version="5.6.0" targetFramework="net47" />
<package id="Swashbuckle.Core" version="5.6.0" targetFramework="net47" /

STEPS TO REPRODUCE:

I have an asp.net webApi application, where I have just installed Swashbuckle. Very similar to this issue when I navigate to http://localhost/myapp/swagger is redirects to http://localhost/swagger/ui/index. If I manually then insert the virtual directory, ie myapp, it works, ie if I manually enter http://localhost/myapp/swagger/ui/index I get the UI that displays my routes.

I have the following setup code

//Startup.cs..

//GlobalConfiguration.Configuration
      // .EnableSwagger(c => c.SingleApiVersion("v1", "A title for your API"))      
      // .EnableSwaggerUi();

      HttpConfiguration httpConfig = new HttpConfiguration();
      SwaggerConfig.Register(httpConfig);      
      
      WebApiConfig.Register(httpConfig, unityContainer);
      app.UseWebApi(httpConfig);

// SwaggerConfig.cs...
And in my SwaggerConfig.cs I have...

    	//[assembly: PreApplicationStartMethod(typeof(SwaggerConfig), "Register")]

		namespace Micromine.MyApp
		{
		  public class SwaggerConfig
		  {
			public static void Register(HttpConfiguration httpConfig)
			{
			  httpConfig
				   .EnableSwagger(c =>
				   {            
                                          // I modified this RootUrl as per FAQ
					   c.RootUrl(req => req.RequestUri.GetLeftPart(UriPartial.Authority) + req.GetRequestContext().VirtualPathRoot.TrimEnd('/'));    
    
					  c.SingleApiVersion("v1", "MyCompany.MyApp");             
					  c.IncludeXmlComments(string.Format(@"{0}\bin\myapp.xml", System.AppDomain.CurrentDomain.BaseDirectory));
				   })
				   .EnableSwaggerUi(c =>
					   {                 
					   });
			}


I have modified the c.RootUrl(req =>req.RequestUri.GetLeftPart(UriPartial.Authority) +req.GetRequestContext().VirtualPathRoot.TrimEnd('/')); as per the FAQ. Before I did this, even when I manually entered thehttp://localhost/myapp/swagger` the routes did not display, as the incorrect url also was entered into the UI "explore" box, however, adding the RootUrl as above fixed this.

The only thing it did NOT fix was the initial navigation to the swagger UI. Note that once I get to the UI, all else seems to work.

EXPECTED RESULT:

Simply some instruction (or otherwise) on how to configure (or work around) getting to the Swagger UI for an asp.net Owin project.

So, when I navigate to http://localhost/myapp/swaggeris redirects tohttp://localhost/myapp/swagger/ui/index`. If solved, would then be good to add this to the FAQ

ACTUAL RESULT:

When I navigate to http://localhost/myapp/swagger is redirects to http://localhost/swagger/ui/index.

pjc2007 avatar Jan 21 '19 23:01 pjc2007

I have the same problem.

alaniemieckota avatar Feb 26 '19 10:02 alaniemieckota

Yep, same for me.

M0ns1gn0r avatar Mar 13 '19 08:03 M0ns1gn0r

Any progress for this issue? I have a similar problem.

GenweiLi avatar Jun 11 '19 15:06 GenweiLi

Any solution for this ?? I'm facing the same issue. Thanks in advance.

orney21d avatar Jun 21 '19 15:06 orney21d

Same problem here.

LandryDubus avatar Oct 07 '19 10:10 LandryDubus

Same problem...

number-phi avatar Mar 31 '20 15:03 number-phi

I've just resolved my problem removing "RootUrl" from the EnableSwagger, Swashbuckle now create the correct URL for my API hosted in a virtual directory.

number-phi avatar Mar 31 '20 16:03 number-phi

I had this. Once you set the RootUrl resolver in EnableSwagger as suggested by @pjc2007, it will work, however the old redirect might be cached by your browser - took me a few minutes to work that out.

swagger.RootUrl(resolver =>
    resolver.RequestUri.GetLeftPart(UriPartial.Authority) + resolver.GetRequestContext().VirtualPathRoot.TrimEnd('/'));

stuartag avatar Jul 24 '20 11:07 stuartag

same problem

nvaghari avatar Aug 12 '20 06:08 nvaghari

I'm hacking it with the use of Referrer as UI is loaded by the browser, the referrer is auto send and this makes it work

        app.UseSwagger(options =>
        {
            //Workaround to use the Swagger UI "Try Out" functionality when deployed behind a reverse proxy with routing
            options.PreSerializeFilters.Add((swagger, httpReq) =>
            {
                //The assumption is being made here that index.html is hosted in the root of a virtual directory where a route can be a root
                //example without a proxy
                //https://example.com/index.html <-- the API is directly accesible at domain root like domain.com/v1/users
                //
                //example with a proxy and routing
                //https://example.com/appx/index.html <-- the API is accesible at domain.com/appx "root" like domain.com/appx/v1/users
                //everything should be relative to domain.com/appx
                if (httpReq.Headers.ContainsKey("Referer"))
                {
                    var referer = httpReq.Headers["Referer"].ToString();
                    var index = referer.IndexOf("index.html");
                    if (index >= 0)
                    {
                        var basePath = referer.Remove(index);
                        swagger.Servers = new List<OpenApiServer> { new OpenApiServer { Url = basePath } };
                    }
                }
            });
        });

Would be nice if Swagger was using JS (window.location) to check the location of index.html (or any other start page is possible to configure) and assume that URL is the base url for all requests

skironDotNet avatar Apr 12 '24 21:04 skironDotNet