ReviewCoreASPHosting.NET | Best and cheap ASP.NET Core 1.0 hosting. Let’s create a versioned and semi-automatically documented Web API, this could be done both for public API, and quite useful for, internal-use API’s as well.

The ASP.NET Core Web API Project

Create a new project Visual C# > .NET Core > ASP.NET Core Web Application and give a descriptive name to your API.

We’re going to add three NuGet packages:

Install-Package Microsoft.AspNetCore.Mvc.Versioning
Install-Package Swashbuckle.AspNetCore -Pre
Install-Package SwashbuckleAspNetVersioningShim -Pre

Two of these packages are prerelease packages but they are fully functional

You can now remove the automatically created ValuesController.cs and let’s add a new HelloController.cs

using Microsoft.AspNetCore.Mvc;

namespace VersionedWebApi.Controllers
{
    /// <summary>
    /// HelloController, just saying Hello World!
    /// </summary>
    [ApiVersion("1.0", Deprecated = true)]
    [Route("api/v{version:apiVersion}/[controller]")]
    public class HelloController : Controller
    {
        /// <summary>
        /// Default Get call returning Hello World!
        /// </summary>
        /// <returns></returns>
        [HttpGet]
        public string Get()
        {
            return "Hello World!";
        }
    }
}

I’ve decorated the class with an ApiVersion attribute stating that this is our version 1.0 HelloController and that it is already deprecated, and also note the modified Route attribute with a v{version:apiVersion} part.

Let’s create a new folder in the Controllers folder called v2 and create a second HelloController.cs in there.

using Microsoft.AspNetCore.Mvc;
using System;

namespace VersionedWebApi.Controllers.v2
{
    /// <summary>
    /// The modern HelloController, all up to date responses
    /// </summary>
    [ApiVersion("2.0")]
    [Route("api/v{version:apiVersion}/[controller]")]
    public class HelloController : Controller
    {
        /// <summary>
        /// Default Get call returning Hello current-year!
        /// </summary>
        /// <returns></returns>
        [HttpGet]
        public HelloWorldModel Get()
        {
            return new HelloWorldModel
            {
                Message = $"Hello {DateTime.Now.Year}!"
            };
        }
    }
 
    /// <summary>
    /// HelloWorldModel class for HelloController
    /// </summary>
    public class HelloWorldModel
    {
        /// <summary>
        /// Message string
        /// </summary>
        public string Message { get; set; }
    }
}

This class is decorated with a 2.0 ApiVersion attribute and features a HelloWorldModel return type with a DateTime.Now part.

Now open up the Startup.cs file and let’s add Versioning support to our Web API.

public void ConfigureServices(IServiceCollection services)
{
    // Add framework services
    var mvcBuilder = services.AddMvc();

    // Adds versioning capabilities, defaulting to version 1.0 calls if available
    services.AddApiVersioning(o =>
    {
        o.AssumeDefaultVersionWhenUnspecified = true;
        o.DefaultApiVersion = new ApiVersion(1, 0);
    });

    // Add generated documentation
    services.AddSwaggerGen(c =>
    {
        SwaggerVersioner.ConfigureSwaggerGen(c, mvcBuilder.PartManager);
    });
}

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

    // Generate swagger.json
    app.UseSwagger();

    // Let's enable SwaggerUI
    app.UseSwaggerUI(c =>
    {
        SwaggerVersioner.ConfigureSwaggerUI(c, partManager);
    });

    app.UseMvc();
}

Open the project’s Properties and go to Debug and change the Launch Url to api/v1/hello and start the application, see the result and change the url v1 to v2.

Now head over to /swagger and see your interactive documentation based on the /swagger/v1.0/swagger.json and /swagger/v2.0/swagger.json generated files.

Leave a Reply

Your email address will not be published. Required fields are marked *