Skip to content
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions src/Swashbuckle.AspNetCore.SwaggerUI/SwaggerUIMiddleware.cs
Original file line number Diff line number Diff line change
Expand Up @@ -163,6 +163,9 @@ private Dictionary<string, string> GetIndexArguments()
{
{ "%(DocumentTitle)", _options.DocumentTitle },
{ "%(HeadContent)", _options.HeadContent },
{ "%(PathCss)", _options.StylesPath },
{ "%(PathBundleJs)", _options.ScriptBundlePath },
{ "%(PathStandaloneJs)", _options.ScriptPresetsPath },
{ "%(ConfigObject)", configObject },
{ "%(OAuthConfigObject)", oauthConfigObject },
{ "%(Interceptors)", interceptors },
Expand Down
15 changes: 15 additions & 0 deletions src/Swashbuckle.AspNetCore.SwaggerUI/SwaggerUIOptions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,21 @@ public class SwaggerUIOptions
/// Gets or sets the optional JSON serialization options to use to serialize options to the HTML document.
/// </summary>
public JsonSerializerOptions JsonSerializerOptions { get; set; }

/// <summary>
/// Gets or sets the path or URL to the Swagger UI JavaScript bundle file.
/// </summary>
public string ScriptBundlePath { get; set; } = "./swagger-ui-bundle.js";

/// <summary>
/// Gets or sets the path or URL to the Swagger UI JavaScript standalone presets file.
/// </summary>
public string ScriptPresetsPath { get; set; } = "./swagger-ui-standalone-preset.js";

/// <summary>
/// Gets or sets the path or URL to the Swagger UI CSS file.
/// </summary>
public string StylesPath { get; set; } = "./swagger-ui.css";
}

public class ConfigObject
Expand Down
6 changes: 3 additions & 3 deletions src/Swashbuckle.AspNetCore.SwaggerUI/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
<head>
<meta charset="UTF-8">
<title>%(DocumentTitle)</title>
<link rel="stylesheet" type="text/css" href="./swagger-ui.css">
<link rel="stylesheet" type="text/css" href="%(StylesPath)">
<link rel="icon" type="image/png" href="./favicon-32x32.png" sizes="32x32" />
<link rel="icon" type="image/png" href="./favicon-16x16.png" sizes="16x16" />
<style>
Expand Down Expand Up @@ -40,8 +40,8 @@
}
</script>

<script src="./swagger-ui-bundle.js"></script>
<script src="./swagger-ui-standalone-preset.js"></script>
<script src="%(ScriptBundlePath)"></script>
<script src="%(ScriptPresetsPath)"></script>
<script>
/* Source: https://gist.github.com/lamberta/3768814
* Parse a string function definition and return a function object. Does not use eval.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -88,5 +88,66 @@ public async Task SwaggerUIMiddleware_CanBeConfiguredMultipleTimes(string swagge
Assert.Contains(version, content);
}
}

[Theory]
[InlineData(typeof(Basic.Startup), "/index.html", "/swagger-ui.js", "/swagger-ui.css", "/swagger-ui-bundle.js", "/swagger-ui-standalone-preset.js")]
[InlineData(typeof(CustomUIConfig.Startup), "/swagger/index.html", "/swagger/swagger-ui.js", "/ext/custom-stylesheet.css", "/ext/custom-javascript.js", "/ext/custom-javascript.js")]
public async Task IndexUrl_ReturnsCustomScripts(
Type startupType,
string indexPath,
string jsPath,
string cssPath,
string scriptBundlePath,
string scriptPresetsPath)
{
var client = new TestSite(startupType).BuildClient();

var indexResponse = await client.GetAsync(indexPath);
Assert.Equal(HttpStatusCode.OK, indexResponse.StatusCode);
var indexContent = await indexResponse.Content.ReadAsStringAsync();
Assert.Contains("SwaggerUIBundle", indexContent);

var jsResponse = await client.GetAsync(jsPath);
Assert.Equal(HttpStatusCode.OK, jsResponse.StatusCode);

var cssResponse = await client.GetAsync(cssPath);
Assert.Equal(HttpStatusCode.OK, cssResponse.StatusCode);

var scriptBundleResponse = await client.GetAsync(scriptBundlePath);
Assert.Equal(HttpStatusCode.OK, scriptBundleResponse.StatusCode);

var scriptPresetsResponse = await client.GetAsync(scriptPresetsPath);
Assert.Equal(HttpStatusCode.OK, scriptPresetsResponse.StatusCode);
}

[Theory]
[InlineData(typeof(CustomUIConfig.Startup), "/swagger/index.html", "/swagger/swagger-ui.js", "/ext/custom-stylesheet-2.css", "/ext/custom-javascript-2.js", "/ext/custom-javascript-2.js")]
public async Task IndexUrl_ReturnsCustomScripts_NotFound(
Type startupType,
string indexPath,
string jsPath,
string cssPath,
string scriptBundlePath,
string scriptPresetsPath)
{
var client = new TestSite(startupType).BuildClient();

var indexResponse = await client.GetAsync(indexPath);
Assert.Equal(HttpStatusCode.OK, indexResponse.StatusCode);
var indexContent = await indexResponse.Content.ReadAsStringAsync();
Assert.Contains("SwaggerUIBundle", indexContent);

var jsResponse = await client.GetAsync(jsPath);
Assert.Equal(HttpStatusCode.OK, jsResponse.StatusCode);

var cssResponse = await client.GetAsync(cssPath);
Assert.Equal(HttpStatusCode.NotFound, cssResponse.StatusCode);

var scriptBundleResponse = await client.GetAsync(scriptBundlePath);
Assert.Equal(HttpStatusCode.NotFound, scriptBundleResponse.StatusCode);

var scriptPresetsResponse = await client.GetAsync(scriptPresetsPath);
Assert.Equal(HttpStatusCode.NotFound, scriptPresetsResponse.StatusCode);
}
}
}
3 changes: 3 additions & 0 deletions test/WebSites/CustomUIConfig/Startup.cs
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,9 @@ public void Configure(IApplicationBuilder app, IWebHostEnvironment env)

// Other
c.DocumentTitle = "CustomUIConfig";
c.StylesPath = "/ext/custom-stylesheet.css";
c.ScriptBundlePath = "/ext/custom-javascript.js";
c.ScriptPresetsPath = "/ext/custom-javascript.js";
c.InjectStylesheet("/ext/custom-stylesheet.css");
c.InjectJavascript("/ext/custom-javascript.js");
c.UseRequestInterceptor("(req) => { req.headers['x-my-custom-header'] = 'MyCustomValue'; return req; }");
Expand Down