Skip to content

Instantly share code, notes, and snippets.

@Xordal
Last active February 28, 2018 15:13
Show Gist options
  • Save Xordal/a940048caf3f9f8acb6eda6d7b3f2859 to your computer and use it in GitHub Desktop.
Save Xordal/a940048caf3f9f8acb6eda6d7b3f2859 to your computer and use it in GitHub Desktop.
RoutePrefix for BaseController inheritance with versioning

PM> Install-Package Microsoft.AspNet.WebApi.Versioning

[System.Web.Http.Authorize]
[ApiVersion("1.0")]
[RoutePrefix("api/v{version:apiVersion}")]
public class BaseApiController : ApiController
namespace Project.WebApi.Helpers
{
using System;
using System.Linq;
using System.Web.Http;
using System.Web.Http.Controllers;
using System.Web.Http.Routing;
using Project.WebApi.Controllers;
/// <summary>
/// Custom direct route provider
/// </summary>
/// <seealso cref="System.Web.Http.Routing.DefaultDirectRouteProvider" />
public class CustomDirectRouteProvider : DefaultDirectRouteProvider
{
/// <summary>
/// Gets the route prefix from the provided controller.
/// </summary>
/// <param name="controllerDescriptor">The controller descriptor.</param>
/// <returns>
/// The route prefix or null.
/// </returns>
protected override string GetRoutePrefix(HttpControllerDescriptor controllerDescriptor)
{
var routePrefix = base.GetRoutePrefix(controllerDescriptor);
var controllerBaseType = controllerDescriptor.ControllerType.BaseType;
if (controllerBaseType == typeof(BaseApiController))
{
var baseRoutePrefixObject = controllerBaseType.CustomAttributes
.FirstOrDefault(x => x.AttributeType == typeof(RoutePrefixAttribute))?.ConstructorArguments
.FirstOrDefault().Value;
String baseRoutePrefix = baseRoutePrefixObject as String;
routePrefix = $"{baseRoutePrefix ?? String.Empty}/{routePrefix}";
}
return routePrefix;
}
}
}
namespace Project.WebApi.Helpers
{
using System;
using System.Net;
using System.Net.Http;
using System.Text;
using Project.Domain.Resources.Errors;
using Project.Infrastructure.Helpers.ErrorResponse;
using Microsoft.Web.Http.Versioning;
/// <summary>
/// Custom error response provider
/// </summary>
/// <seealso cref="Microsoft.Web.Http.Versioning.IErrorResponseProvider" />
public class CustomErrorResponseProvider : IErrorResponseProvider
{
/// <summary>
/// Creates and returns a new error response given the provided context.
/// </summary>
/// <param name="context">The <see cref="T:Microsoft.Web.Http.Versioning.ErrorResponseContext">error context</see> used to generate response.</param>
/// <returns>
/// The generated <see cref="T:System.Net.Http.HttpResponseMessage">response</see>.
/// </returns>
/// <exception cref="NotImplementedException"></exception>
public HttpResponseMessage CreateResponse(ErrorResponseContext context)
{
HttpResponseMessage response = context.Request.CreateResponse(HttpStatusCode.Gone);
response.Content = new StringContent(ErrorResponseHelper.ResultByErrorCode(nameof(Errors.UnsupportedApiVersion)),
Encoding.UTF8, "application/json");
return response;
}
}
}
namespace Project.WebApi
{
using System.Web.Http;
using System.Web.Http.Routing;
using Project.WebApi.Filters;
using Project.WebApi.Helpers;
using Microsoft.Web.Http.Routing;
using Microsoft.Web.Http.Versioning;
/// <summary>
/// WebApi config.
/// </summary>
public static class WebApiConfig
{
/// <summary>
/// Registers the specified configuration.
/// </summary>
/// <param name="config">The configuration.</param>
public static void Register(HttpConfiguration config)
{
// Web API configuration and services
// Registering action filters
config.Filters.Add(new BusinessLogicFilterAttribute());
config.Filters.Add(new ValidateModelFilterAttribute());
config.Filters.Add(new BusinessExceptionFilterAttribute());
config.Filters.Add(new GlobalExceptionFilterAttribute());
// added to the web api configuration in the application setup
var constraintResolver = new DefaultInlineConstraintResolver()
{
ConstraintMap =
{
["apiVersion"] = typeof( ApiVersionRouteConstraint )
}
};
// Web API routes
config.MapHttpAttributeRoutes(constraintResolver, new CustomDirectRouteProvider());
// allow a client to call you without specifying an api version
// since we haven't configured it otherwise, the assumed api version will be 1.0
config.AddApiVersioning(o =>
{
o.AssumeDefaultVersionWhenUnspecified = true;
o.ApiVersionReader = new UrlSegmentApiVersionReader();
o.ErrorResponses = new CustomErrorResponseProvider();
});
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional }
);
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment