How to Setup and Customize Swagger with ASP.NET MVC
Table of Contents
- Introduction
- What's Swagger?
- Use Azure API App Template with Swagger
- Can I Use a Customized Stylesheet for Swagger?
- Can I Add My Own JavaScript File to Swagger API Documents?
- Can We Change the Entire HTML?
- Add .NET XML Comment for Swagger's API Description
- Conclusion
Introduction
This walkthrough tutorial is about how to set up Swagger with ASP.NET MVC API by using Visual Studio 2015, and also provides steps on how to customize the Swagger UI.
What's Swagger?
Swagger could provide richer documentation for your API, but that's not all — it provides tools to design, test, and document your API. Although this blog just focuses on how to set up Swagger UI on Visual Studio 2015's ASP.NET API project. ASP.NET MVC also has a Web API Helper page, but unlike Swagger, which is more powerful with client generation, discoverability, and broader developer support.
This blog will show how to use Swagger with an ASP.NET MVC API project and provide a list of how-tos.
With a Swagger-enabled API, you get interactive documentation, client SDK generation and discoverability.
Install-Package Swashbuckle
The following are a few resources related to Swagger.
-
Swashbuckle
-
swagger-codegen
-
swagger-ui
-
OpenAPI Specification
Use Azure API App Template with Swagger
You can use Swagger with Visual Studio 2015, ASP.NET 4.5.2 Templates. Once you use Visual Studio and create a web application using the Azure API App template, in your solution you should see the following Swagger entry in the package file.

You will find the NuGet library Swashbuckle, which is the .NET version of
Swagger. If you want to use the latest NuGet version, you can use NuGet to
uninstall the package and install the latest NuGet package again.

SwaggerConfig, EnableSwaggerUi, and Basic Configuration
After installing Swashbuckle, you will see a SwaggerConfig under your
App_Start folder. This SwaggerConfig is the starting point to enable
Swagger. If you already have the following content, then your setup is
done. We should see the API documentation generated by Swagger.
[assembly: PreApplicationStartMethod(typeof(SwaggerConfig), "Register")]
namespace WebApplication1
{
public class SwaggerConfig
{
public static void Register()
{
var thisAssembly = typeof(SwaggerConfig).Assembly;
GlobalConfiguration.Configuration
.EnableSwagger(c =>
// {...
// this will enable swagger UI
.EnableSwaggerUi(c =>
Build the Solution and Check the URL
Navigate to {yoururl}/swagger or {yoururl}/swagger/ui/index.
You should be able to see the following Swagger UI documentation page. I
have two Web APIs, TestController and
ValuesController. As you can see, it contains a search feature
and you can try it out.


However, I also had the following questions when I first saw these pages generated by Swagger.
-
Can I change this API document's UI, including the logo and stylesheet?
-
Can I add JavaScript to this?
-
Can I change the URL instead of /swagger?
-
Can I add my own page to this auto-generated page?
-
Can I make certain Web APIs not show up?
-
Can I turn the Swagger API documentation off in production, but keep it only in development?
I might not cover all these questions I have in mind, but I will give them a try and list them here.
Can I Use a Customized Stylesheet for Swagger?
Let's assume I want to change the following style, which changes the header
background color to #704C8F.
1. CSS File
.swagger-section #header {
background-color: #704C8F;
padding: 14px;
}
2. SwaggerConfig
.EnableSwaggerUi(c => {
c.InjectStylesheet(Assembly.GetAssembly(typeof(WebApiApplication)), "WebApplication2.styles.swagger_test.css");
3. Global.asax
How the WebApiApplication Looks
The SwaggerConfig's InjectStyleSheet's first parameter needs to pass the
current application's assembly. The second parameter is a little tricky. The
filename WebApplication2.styles.swagger_test.css is
Project Folder name.{folder name} and the file name.
namespace WebApplication2
{
public class WebApiApplication : System.Web.HttpApplication
{
protected void Application_Start()
{
AreaRegistration.RegisterAllAreas();
GlobalConfiguration.Configure(WebApiConfig.Register);
RouteConfig.RegisterRoutes(RouteTable.Routes);
}
}
}
4. Styles File Location
Also, this is very important — you must set the file's Build Action to Embedded Resource.
5. After Steps 1–4, How the Page Looks

Can I Add My Own JavaScript File to Swagger API Documents?
You are able to do it as follows. Assume you have a JavaScript file like this.
1. JavaScript
(function () {
function init() {
console.info("init for my swagger function");
$("#explore").click(function () {
alert("you clicked explore");
});
}
init();
})();
2. JavaScript File Location and Build Action Property
3. SwaggerConfig Class
Set the JavaScript path as a string type like the following.
var myAssembly = Assembly.GetAssembly(typeof(WebApiApplication));
c.InjectJavaScript(myAssembly, "WebApplication2.js.swagger_test.js");
4. Done, Check the Page
When the page loads, you can see the JavaScript console message. Now you can add JavaScript to the page. My next question is: can I change the default HTML?

Now, We Know We Can Change JavaScript, CSS — Can We Change the Entire HTML?
Yes, and the main features will still work if you use Swagger's existing JavaScript. The following is how we can do it.
1. HTML Files
This time I want to add two HTML files. After creating these HTML files, you also have to change the Build Action to Embedded Resource again.

swagger_test.html
Bomm!!!!
OtherVersion.html
<!DOCTYPE html>
Swagger UI My Own Version
<!-- Some basic translations -->
<!-- -->
<!-- -->
<!-- -->
$(function () {
var url = window.location.search.match(/url=([^&]+)/);
if (url && url.length > 1) {
url = decodeURIComponent(url[1]);
} else {
url = "http://petstore.swagger.io/v2/swagger.json";
}
// Get Swashbuckle config into JavaScript
function arrayFrom(configString) {
return (configString !== "") ? configString.split('|') : [];
}
function stringOrNullFrom(configString) {
return (configString !== "null") ? configString : null;
}
window.swashbuckleConfig = {
rootUrl: 'http://localhost:65343',
discoveryPaths: arrayFrom('swagger/docs/v1'),
booleanValues: arrayFrom('true|false'),
validatorUrl: stringOrNullFrom('http://localhost:65343/validator'),
customScripts: arrayFrom('ext/WebApplication2-js-swagger_test-js'),
docExpansion: 'none',
oAuth2Enabled: ('false' == 'true'),
oAuth2ClientId: '',
oAuth2ClientSecret: '',
oAuth2Realm: '',
oAuth2AppName: '',
oAuth2ScopeSeperator: ' ',
oAuth2AdditionalQueryStringParams: JSON.parse('{}')
};
// Pre load translate...
if(window.SwaggerTranslator) {
window.SwaggerTranslator.translate();
}
window.swaggerUi = new SwaggerUi({
url: swashbuckleConfig.rootUrl + "/" + swashbuckleConfig.discoveryPaths[0],
dom_id: "swagger-ui-container",
booleanValues: swashbuckleConfig.booleanValues,
onComplete: function(swaggerApi, swaggerUi){
if (typeof initOAuth == "function" && swashbuckleConfig.oAuth2Enabled) {
initOAuth({
clientId: swashbuckleConfig.oAuth2ClientId,
clientSecret: swashbuckleConfig.oAuth2ClientSecret,
realm: swashbuckleConfig.oAuth2Realm,
appName: swashbuckleConfig.oAuth2AppName,
scopeSeparator: swashbuckleConfig.oAuth2ScopeSeperator,
additionalQueryStringParams: swashbuckleConfig.oAuth2AdditionalQueryStringParams
});
}
if(window.SwaggerTranslator) {
window.SwaggerTranslator.translate();
}
$('pre code').each(function(i, e) {
hljs.highlightBlock(e)
});
addApiKeyAuthorization();
window.swaggerApi = swaggerApi;
_.each(swashbuckleConfig.customScripts, function (script) {
$.getScript(script);
});
},
onFailure: function(data) {
log("Unable to Load SwaggerUI");
},
docExpansion: swashbuckleConfig.docExpansion,
jsonEditor: false,
apisSorter: null, // default to server
defaultModelRendering: 'schema',
showRequestHeaders: false
});
if (window.swashbuckleConfig.validatorUrl !== '')
window.swaggerUi.options.validatorUrl = window.swashbuckleConfig.validatorUrl;
function addApiKeyAuthorization(){
var key = encodeURIComponent($('#input_apiKey')[0].value);
if (key && key.trim() != "") {
var apiKeyAuth = new SwaggerClient.ApiKeyAuthorization("api_key", key, "query");
window.swaggerUi.api.clientAuthorizations.add("api_key", apiKeyAuth);
log("added key " + key);
}
}
$('#input_apiKey').change(addApiKeyAuthorization);
// if you have an apiKey you would like to pre-populate on the page for demonstration purposes...
/*
var apiKey = "myApiKeyXXXX123456789";
$('#input_apiKey').val(apiKey);
*/
window.swaggerUi.load();
function log() {
if ('console' in window) {
console.log.apply(console, arguments);
}
}
});
Damn, I love this! Swagger!
2. SwaggerConfig for HTML
c.CustomAsset("swagger_test", myAssembly, "WebApplication2.html.swagger_test.html");
c.CustomAsset("OtherVersion", myAssembly, "WebApplication2.html.OtherVersion.html");
3. Check the Browser
Now, you're going to ask: what's the URL? I didn't figure it out at
first, but it looks like Swagger uses the file name as the URL. Since
their default page is /swagger/ui/index, my new files' URLs will be
/swagger/ui/OtherVersion and
/swagger/ui/swagger_test.
The following is one of my new pages, OtherVersion. Isn't this great? As a developer, when you use another UI framework and you can replace CSS, JavaScript, and HTML while keeping the original logic, that's just fantastic.

Add .NET XML Comment for Swagger's API Description
ASP.NET WebAPI's default API helper documentation also looks for the DLL's XML comments for descriptions. We can do that in Swagger too.
1. Project Property
The first thing you need to do is go to the project that contains the API controller and check the XML documentation file. When building the solution, Visual Studio will update the XML with comments you add to the class. Also, Swagger will later read the XML comments as descriptions for the API.

2. SwaggerConfig Setting
The next important thing is that Swagger has not registered the API XML. You can add it as follows.
c.IncludeXmlComments(string.Format(@"{0}\bin\APIDemo.XML", System.AppDomain.CurrentDomain.BaseDirectory));
The following are examples of the WebAPI controller and the API Model class's XML documentation.
///
/// my product
///
public class Product
{
///
/// product id
///
public Guid GuidId { get; set; }
///
/// product Id
///
public int ProductId { get; set; }
///
/// product name
///
public string ProductName { get; set; }
///
/// product price
///
public decimal Price { get; set; }
///
/// product unit
///
public int Unit { get; set; }
///
/// ProductController API
///
public class ProductController : ApiController
{
///
/// products data
///
public static ListProducts
{
get
{
return new List
{
new Product(Guid.NewGuid(), 122, "Product A", 300, 1),
new Product(Guid.NewGuid(), 333, "Product B", 400, 10),
new Product(Guid.NewGuid(), 444, "Product C", 500, 20),
new Product(Guid.NewGuid(), 555, "Product D", 600, 15),
new Product(Guid.NewGuid(), 777, "Product E", 700, 5)
};
}
}
///
/// get values for products
///
///
public IEnumerable Get()
{
return Products;
}
3. Done! Let's Browse the API Documentation
Now we're done. After building the solution, you should see your XML comments added to the C# class on the Swagger API documentation page.

Conclusion
Swagger with ASP.NET MVC provides very powerful API documentation and it is very flexible. You can customize the CSS, JavaScript, and HTML while retaining the core Swagger functionality.
Check the Code mentioned in this blog.