There are several reasons why an API might be needed in a Kentico website. Maybe you have a page that needs to display multiple pieces of data or products dynamically and on the fly based on user interaction and do not want to have to reload the page each time. Maybe you want to view some statistics or run tests on some data, but do not want to expose that to the outside world. Maybe you are a store that supplies products to other distributors and want a way for customers to access your data from their own sites. All of these and many more possible scenarios can easily be provided for using an API within a Kentico 12 MVC site.
Kentico 12 has full MVC capability and runs on .NET and the new Kentico 12 Dancing Goat sample site is a complete MVC site. What we will do is add a simple Web API to the project. It will have a single API endpoint to get the SKU Numbers of all products. We will also tie into the
dependency injection already implemented in the Dancing Goat site. While this requires a bit of set up, it will aid in scalability and maintainability of our API endpoint as well as any others we might want to add going forward.
Setting Up Dependency Injection
Dancing Goat uses
Autofac for dependency injection, but by default does not have the library necessary to register
ApiController
implementations. Install this dependency by right-clicking the project and selecting “Manage NuGet Packages”:
Then search for and install “Autofac.WebApi2”:
Make sure it is “WebApi2” and not just “WebApi” or things will not work correctly. Next, we need to add the code to make sure everything is registered properly.
- Open DependencyResolverConfig.cs in the “App_Start” directory.
- Add
using Autofac.Integration.WebApi;
to gain access to the extension methods.
- Now, at the bottom of the
Register()
method update the code like this:
var container = builder.Build();
// This existing line is slightly updated here
DependencyResolver.SetResolver(new AutofacDependencyResolver(container));
System.Web.Http.GlobalConfiguration.Configuration.DependencyResolver =
new AutofacWebApiDependencyResolver(container);
Then add the API controller registration code right below the MVC controller registration code in the
ConfigureDependencyResolverForMvcApplication()
method:
// Register controllers. This should already be here for registering MVC controllers
builder.RegisterControllers(typeof(DancingGoatApplication).Assembly);
// Register Api Controllers
builder.RegisterApiControllers(typeof(DancingGoatApplication).Assembly);
Adding all of this will allow us to take advantage of the services implemented and registered within the site and use them in our API code.
Adding an Area for the API
The project comes pre-installed with the necessary Web API libraries from Microsoft, but we still have some setup to do first. There are several ways to add an API endpoint, but to keep our Web API code separate from the rest of the site we will put it in a new “Area”. To do this, right click on the Dancing Goat project and select Add -> Area. Simply name it “Api”.
Visual Studio will scaffold out some files and folders for using the new area.
We do not need anything in the Views folder, so just delete that folder with its contents. Also, make sure that the following is added in the
Application_Start()
method inside
Global.asax.cs above the line where all the other routes are registered:
// Register Areas before registering other routes
System.Web.Mvc.AreaRegistration.RegisterAllAreas();
// This line should already be in Application_Start()
RouteConfig.RegisterRoutes(RouteTable.Routes);
We also need to update the route registration for our new area to get our endpoint working as an API endpoint in the new area. Open up the
ApiAreaRegistration.cs file, remove the code in the
RegisterArea()
method and update the code like this:
public override void RegisterArea(AreaRegistrationContext context)
{
context.Routes.MapHttpRoute(
"Api_DefaultWebApiRoute",
"Api/{controller}/{id}",
new { id = RouteParameter.Optional }
);
}
The
MapHttpRoute
methods are extension methods so make sure to add
using System.Web.Http;
at the top of the file. The method call registers the routes for any
System.Web.Http.ApiController
as opposed to the original code that registers routes for a
System.Web.Mvc.Controller
.
Adding the API Code
Now we can create a new
ApiController
to use for a new API endpoint.
- Right-click on the “Controllers” folder in the new area and select Add -> Controller.
- Select an empty Web API 2 controller, give it a name and add it to your project.
We named ours “ProductSkusController” and as mentioned at that beginning it will be used for listing all product SKU Numbers. Here is what this API controller looks like in its entirety:
using DancingGoat.Repositories;
using System.Collections.Generic;
using System.Linq;
using System.Web.Http;
namespace DancingGoat.Areas.Api.Controllers
{
public class ProductSkusController : ApiController
{
// Existing Dancing Goat repositories
private readonly ICoffeeRepository mCoffeeRepository;
private readonly IBrewerRepository mBrewerRepository;
// Constructor with injected dependencies
public ProductSkusController(
ICoffeeRepository coffeeRepository,
IBrewerRepository brewerRepository
)
{
mCoffeeRepository = coffeeRepository;
mBrewerRepository = brewerRepository;
}
public IEnumerable<string> Get()
{
var coffeeSkus = mCoffeeRepository
.GetCoffees(null)
.Select(coffee => coffee.SKU.SKUNumber);
var brewerSkus = mBrewerRepository
.GetBrewers(null)
.Select(brewer => brewer.SKU.SKUNumber);
return coffeeSkus.Concat(brewerSkus);
}
}
}
Now it should all be ready to go. Start up the site and navigate to “/Api/ProductSkus”. You should be able to see the SKU numbers coming back from the GET request, but if you notice it is not coming back as JSON formatted data which is standard for web APIs. It is formatted as XML:
To fix this we need to add a couple more lines of code. Inside of the
Global.asax.cs file in the
Application_Start()
method add the following lines of code (you can alternatively put this in a separate method inside
ApplicationConfig.cs in the “App_Start” folder and call that method from
Application_Start()
to make it a little cleaner):
// Enable JSON formatting with Camelcase property names
var jsonFormatter = System.Web.Http.GlobalConfiguration.Configuration.Formatters.JsonFormatter;
jsonFormatter.SupportedMediaTypes
.Add(new System.Net.Http.Headers.MediaTypeHeaderValue("text/html") );
jsonFormatter.SerializerSettings.ContractResolver = new Newtonsoft.Json.Serialization.CamelCasePropertyNamesContractResolver();
With that added the result coming from the API should look like this:
Finally, the result of all that hard work! Obviously, this is a fairly simple API and your requirements and the libraries you use might be different, but adding a Web API controller for an MVC project will likely be very similar and going the extra mile using dependency injection will help out immensely. Hopefully, this will help you or someone else out in getting an API up and running quickly in the future.