ASP.NET Core 1.0 MVC API documentation using Swashbuckle Swagger

This article shows how to document your ASP.NET Core 1.0 MVC API using Swagger with Swashbuckle. Per default, it does not use your xml comments in the code and this needs to be configured if required.

Code: https://github.com/damienbod/AspNet5GeoElasticsearch

2016.07.03 Updated to ASP.NET Core RTM
2016.06.04 Updated to ASP.NET Core RC2 dotnet

Step 1: Add the required NuGet packages to the dependencies in the project.json file.

 "dependencies": {

        "Swashbuckle.SwaggerGen": "6.0.0-beta901",
        "Swashbuckle.SwaggerUi": "6.0.0-beta901"

},

Step 2: Produce the .xml file which contains the xml comments when building. Click the produce outputs on build checkbox in your project file.

SwaggerProjectConfig

Or set the ProduceOutputsOnBuild property in the project xproj file.

<ProduceOutputsOnBuild>True</ProduceOutputsOnBuild>

Step 3: Configure Swashbuckle.SwaggerGen in the Startup class ConfigureServices method.

You need to define your path to the comments xml file, which can be found in the artifacts folder. This should be saved in a config file.

The ConfigureSwaggerDocument with OperationFilter method is required so that the xml comments are added to the documentation, and also ConfigureSwaggerSchema with ModelFilter

public void ConfigureServices(IServiceCollection services)
{
	var pathToDoc = Configuration["Swagger:Path"];

	services.AddMvc();

	services.AddSwaggerGen();
	services.ConfigureSwaggerGen(options =>
	{
		options.SingleApiVersion(new Info
		{
			Version = "v1",
			Title = "Geo Search API",
			Description = "A simple api to search using geo location in Elasticsearch",
			TermsOfService = "None"
		});
		options.IncludeXmlComments(pathToDoc);
		options.DescribeAllEnumsAsStrings();
	});

	services.AddScoped<ISearchProvider, SearchProvider>();
}

Step 4: Use swagger in the Startup class Configure method.

UseSwaggerGen and UseSwaggerUi

public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
{
	loggerFactory.AddConsole(Configuration.GetSection("Logging"));
	loggerFactory.AddDebug();

	if (env.IsDevelopment())
	{
		app.UseDeveloperExceptionPage();
		app.UseBrowserLink();
	}
	else
	{
		app.UseExceptionHandler("/Home/Error");
	}

	app.UseStaticFiles();

	app.UseMvc(routes =>
	{
		routes.MapRoute(
			name: "default",
			template: "{controller=Home}/{action=Index}/{id?}");
	});

	app.UseSwagger();
        app.UseSwaggerUi();
}

Step 5: Create a Controller API with your documentation:

using Microsoft.AspNet.Mvc;
using AspNet5GeoElasticsearch.ElasticsearchApi;
using AspNet5GeoElasticsearch.Models;

using Newtonsoft.Json;
using Swashbuckle.SwaggerGen.Annotations;

namespace AspNet5GeoElasticsearch.Controllers
{
    /// <summary>
    /// This class is used as an api for the search requests.
    /// </summary>
    [Route("api/[controller]")]
    [Produces("application/json")]
    public class SearchController : Controller
    {
        private readonly ISearchProvider _searchProvider;

        public SearchController(ISearchProvider searchProvider)
        {
            _searchProvider = searchProvider;
        }

        /// <summary>
        /// This method returns the found documents from Elasticsearch
        /// </summary>
        /// <param name="maxDistanceInMeter">Distance in meters from your location</param>
        /// <param name="centerLongitude">center Longitude </param>
        /// <param name="centerLatitude">center Latitude </param>
        /// <returns>All the documents which were found</returns>
        [HttpGet]
        [Produces(typeof(MapModel))]
        [SwaggerResponse(System.Net.HttpStatusCode.OK, Type = typeof(MapModel))]
        [Route("GeoSearch")]
        public ActionResult Search(uint maxDistanceInMeter, double centerLongitude, double centerLatitude)
        {
            var searchResult = _searchProvider.SearchForClosest(maxDistanceInMeter, centerLongitude, centerLatitude);
            var mapModel = new MapModel
            {
                MapData = JsonConvert.SerializeObject(searchResult),
                CenterLongitude = centerLongitude,
                CenterLatitude = centerLatitude,
                MaxDistanceInMeter = maxDistanceInMeter
            };

            return Ok(mapModel);
        }

        /// <summary>
        /// Inits the Elasticsearch documents
        /// </summary>
        [HttpPost]
        [Route("InitData")]
        public ActionResult InitData()
        {
            initSearchEngine();
            return Ok();
        }

        private void initSearchEngine()
        {
            if (!_searchProvider.MapDetailsIndexExists())
            {
                _searchProvider.InitMapDetailMapping();
                _searchProvider.AddMapDetailData();
            }
        }
    }
}

This can then be viewed using ./swagger/ui

http://localhost:21453/swagger/ui/index.html

aspnet5Mvc6Swagger_02

Links:

https://github.com/domaindrivendev/Swashbuckle

https://github.com/domaindrivendev/Ahoy

http://blog.sluijsveld.com/28/01/2016/CustomSwaggerUIField/

42 comments

  1. Very timely post as I also need to look into this shortly. Thanks🙂

    1. Thanks for the comment

      greetings Damien

  2. […] ASP.NET 5 MVC 6 API documentation using Swashbuckle Swagger // Software Engineering […]

  3. […] ASP.NET 5 MVC 6 API documentation using Swashbuckle Swagger – damienbod shares a look at the process of generating documentation for your MVC 6 API using the Swashbuckle Swagger library […]

  4. hashname · · Reply

    Thanks.
    I would use System.AppDomain.CurrentDomain.BaseDirectory + FileName instead of hardcoding to get the xml path

    1. Thanks, I’ll change this.

      Greetings Damien

    2. Noone · · Reply

      This doesn’t work with .NET Core Sherlocks…

  5. […] ASP.NET 5 MVC 6 API documentation using Swashbuckle Swagger […]

  6. […] Documenter son API ASP.NET MVC 6 avec Swagger. […]

  7. […] ASP.NET 5 MVC 6 API Documentation using Swashbuckle Swagger, by damienbod. […]

  8. […] ASP.NET 5 MVC 6 API Documentation using Swashbuckle Swagger : Swagger를 이용해 MVC 6 API를 문서화하는 방법을 damienbod가 설명합니다. […]

  9. […] ASP.NET 5 MVC 6 API documentation using Swashbuckle Swagger […]

  10. Thanks! Saved my day!
    Unfortunately, it only works fine on localhost. When executed in Azure AppService, app.UseSwaggerGen(); in Startup.Configure() throws exception and I get 500

    1. Jeffrey Kittiyachavalit · · Reply

      That’s because of the path to the xml comments are hard coded. You can remove the operation filter that uses that path and it will work but you won’t get comments for the api doc. I am trying to figure out how to set a relative path to the xml file but haven’t figured it out yet.

    2. It’s because the path the the xml comments file is hard coded. If you remove the line
      options.OperationFilter(new Swashbuckle.SwaggerGen.XmlComments.ApplyXmlActionComments(pathToDoc));
      it will run fine but you won’t get the nifty comments. I am still trying to figure out how to reference the file that will work in a production environment.

      1. Let us know if you managed to run it in production.

      2. The path to the XML docs could be saved to a config file and this could be changed per deployment.

        If you want, I could update the demo so that it can be deployed to production, test servers. With Azure, I don’t know as I have no experience here.

        Greetings Damien

      3. That would be great! Bear in mind that the artifacts folder is not deployed to production

      4. Hi Jeffrey, Have you figured this out? I am also missing the comments when deploying to Azure web apps…

      5. I also ran into the same problem but got the fix.

        private string GetXmlCommentsPath()
        {
        var app = PlatformServices.Default.Application;
        return System.IO.Path.Combine(app.ApplicationBasePath, “WebAPIWithSwagger.xml”);
        }

        http://www.talkingdotnet.com/add-swagger-to-asp-net-core-web-api/

    3. Thanks for the feedback.

      Swagger Path is now defined using a config file. This can be changed as required now depending on your hosting environment.

      Greetings Damien

  11. Muqeet Khan · · Reply

    @damienbod Good article. However, you should update it to let people know they need to add app.UseSwaggerGen() … right after app,UseMvc() … I am adding a bunch of roles after app.UseMvc and “using” SwaggerGen and SwaggerUI after that leads to 404… I am not sure if this is by design or a bug in Swashbuckle or Asp.Net…

    1. HI Maqeet Khan thanks, for this info. I plan to update this week, also need to fix the path, if you have the code, maybe you could do a pull request in gitHub and I’ll merge it, thanks again greetings Damien

    2. Hi Muqeet Khan
      I’ve added a comment now.
      Greetings Damien

  12. Bret Hillbun · · Reply

    @damienbod Thank you for taking the time to write this article. I’ve run into a strange situation where the Response models themselves do not seem to be reading the XML comments even though they are defined within the XML document itself. I used the same path for both Apply methods as your example shows so I’m fairly certain it isn’t a file path issue. Have you tested this at all as it seems like maybe the RC1 release of Swashbuckle may be having some kind of issue here with models / properties.

    1. HI Bret

      Thanks for your comment. I have checked this and the returned model is displayed with XML comments. The committed version has no comments. I added some and the rc1 version returns the XML comments in the api doc.

      Greetings Damien

  13. Thanks! It works properly. Great job.
    Do You know how to use custom index.hml or css ?
    It was possible in MVC 5 using CustomAsset option, but there is no such option in MVC 6.

    1. I haven’t tested, but i think custom index.html and css are now out of the box. Just create a folder structure in your API like on this example:
      https://github.com/domaindrivendev/Ahoy/tree/6.0.0-rc1-final/test/WebSites/CustomizedUi/wwwroot/swagger/ui

      1. Thanks for pointing me out. Custom files must be placed in wwwroot/swagger/ui subfolder. The only thing that needs to be done is commenting out body of addApiKeyAuthorization() function in index.html example file. It causes javascript error. Not overwritten files are taken from embended resource as expected.

  14. I think there are break changes coming on the next release!
    If you compare examples from version used here (6.0.0-rc1-final) https://github.com/domaindrivendev/Ahoy/blob/6.0.0-rc1-final/test/WebSites/Basic/Startup.cs
    and current Master version: https://github.com/domaindrivendev/Ahoy/blob/master/test/WebSites/Basic/Startup.cs

  15. Hi Damien, This doesn’t work in MVC6 .

    1. HI Hari

      What doesn’t work for you?

      Have you tried /swagger/ui/index.html

      Greetings Damien

  16. dzolnjan · · Reply

    Is there way to security definitions like oauth2?

    1. Hi Daniel

      Yes, but I haven’t tried it myself.

      Here’s an example that might help:

      http://danielwertheim.se/use-identityserver-in-swaggerui-to-consume-a-secured-asp-net-webapi/

  17. is this already compatible with rc2 preview of the .net core?

    1. Hi

      No , not yet, only RC1, I will update this when RC2 is released.

      Greetings Damien

      1. Just checking back to see if there is an ETA for RC2 support🙂

  18. Dzivo · · Reply

    Was anybody able to make this work with Angular2 i have problems with routing it is always loading my angular2 index.html

    1. Hi Dzivo You need to change your routing middleware in the Startup class so that the Angular2 client routing is not using for this

      Greetings Damien

  19. John Waters · · Reply

    When I deploy a .net core app to Azure, the Xml files dont seem to be deployed (even though I have Output enabled in the release config). How do I get the xml files deployed?

  20. Hi John, try adding it to the publishOptions in the project.json file.
    Greetings Damien

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: