In this article, I am going to discuss Web API Versioning Using Custom Media Types i.e. Vendor Specific Media Types with an example. This is a continuation part of our previous article, so please read our previous article before proceeding to this article where we discussed Web API Versioning Using Accept Header.
So what we want to do here is, instead of using the built-in media types such as application/json or application/xml, we want to use our custom media type which is shown in the below postman request.
Notice that in the media type, we have specified the version of the service that we want. The custom media types are prefixed with vnd which indicates that this media type is a vendor-specific media type.
So what we need to do from our CustomControllerSelector class is to read the version number from the custom media type that we have specified in the request.
Modify the CustomControllerSelector class as shown below where we implement the logic to read the version number from the custom media type. The code is self-explanatory, so please go through the lines.
CustomControllerSelector
Now specify the custom media type and set the version as 2 and issue a request, then you will get version 2 of the employee objects as expected as shown in the below image.
That’s work as expected. But there is a problem. The problem is if you specify that you want the data in XML format instead of JSON format in the request as shown below, then you will get the data in JSON format instead of the XML format.
The reason is, we have not added our custom Media Type to the respective media type formatters i.e. JsonFormatter and XmlFormatter.
Adding Custom Media Types:
Include the following two lines of code within the WebApiConfig.cs file to add our custom media types to the JsonFormatter
Similarly, include the following two lines of code within the WebApiConfig.cs file to add the custom media types to the XmlFormatter
So at this point, the complete code of the WebApiConfig.cs is given below.
In the next article, I am going to discuss How to Enable SSL in Visual studio Development Server with example. Here, in this article, I try to explain how to implement Web API Versioning Using Custom Media Types step by step with an example. I hope this article will help you with your needs. I would like to have your feedback. Please post your feedback, question, or comments about this article.
Summary:
I hope this post will be helpful to understand how to configure Web API Versioning Using Custom Media Types
Please share this post with your friends and colleagues.
For any queries please post a comment below.
Happy Coding 😉
So what we want to do here is, instead of using the built-in media types such as application/json or application/xml, we want to use our custom media type which is shown in the below postman request.
Notice that in the media type, we have specified the version of the service that we want. The custom media types are prefixed with vnd which indicates that this media type is a vendor-specific media type.
So what we need to do from our CustomControllerSelector class is to read the version number from the custom media type that we have specified in the request.
Modify the CustomControllerSelector class as shown below where we implement the logic to read the version number from the custom media type. The code is self-explanatory, so please go through the lines.
CustomControllerSelector
using System.Linq; using System.Net.Http; using System.Text.RegularExpressions; using System.Web.Http; using System.Web.Http.Controllers; using System.Web.Http.Dispatcher; namespace WebAPIVersioning.Custom { // Derive the CustomControllerSelector from the DefaultHttpControllerSelector class public class CustomControllerSelector : DefaultHttpControllerSelector { private HttpConfiguration _config; public CustomControllerSelector(HttpConfiguration config) : base(config) { _config = config; } public override HttpControllerDescriptor SelectController(HttpRequestMessage request) { // First fetch all the available Web API controllers var controllers = GetControllerMapping(); // Get the controller name and the parameter values from the request URI var routeData = request.GetRouteData(); // Get the controller name from route data. // The name of the controller in our case is "Employees" var controllerName = routeData.Values["controller"].ToString(); // Set the Default version number to 1 string versionNumber = "1"; // Get the version number from the Custom media type // We need to use the regular expression for mataching the pattern of the // media type. We have given a name for the matched group that contains // the version number which enables us to retrieve the version number // using the group name("version") instead of ZERO based index string regex = @"application\/vnd\.dotnettutorials\.([a-z]+)\.v(?<version>[0-9]+)\+([a-z]+)"; // Users can include multiple Accept headers in the request. // So we need to check atlest if any of the Accept headers has our custom // media type by checking if there is a match with regular expression specified var acceptHeader = request.Headers.Accept .Where(a => Regex.IsMatch(a.MediaType, regex, RegexOptions.IgnoreCase)); // If there is atleast one Accept header with our custom media type if (acceptHeader.Any()) { // Retrieve the first custom media type var match = Regex.Match(acceptHeader.First().MediaType, regex, RegexOptions.IgnoreCase); // From the version group, get the version number versionNumber = match.Groups["version"].Value; } if (versionNumber == "1") { // if the version number is 1, then append V1 to the controller name. // So at this point the, controller name will become EmployeesV1 controllerName = controllerName + "V1"; } else { // if version number is 2, then append V2 to the controller name. // So at this point the controller name will become EmployeesV2 controllerName = controllerName + "V2"; } HttpControllerDescriptor controllerDescriptor; if (controllers.TryGetValue(controllerName, out controllerDescriptor)) { return controllerDescriptor; } return null; } } }That’s it; we are done with our implementation. Build the solution and issue a request without using the custom media type from the postman. You will get version 1 of employee objects in JSON format as shown below.
Now specify the custom media type and set the version as 2 and issue a request, then you will get version 2 of the employee objects as expected as shown in the below image.
That’s work as expected. But there is a problem. The problem is if you specify that you want the data in XML format instead of JSON format in the request as shown below, then you will get the data in JSON format instead of the XML format.
The reason is, we have not added our custom Media Type to the respective media type formatters i.e. JsonFormatter and XmlFormatter.
Adding Custom Media Types:
Include the following two lines of code within the WebApiConfig.cs file to add our custom media types to the JsonFormatter
Similarly, include the following two lines of code within the WebApiConfig.cs file to add the custom media types to the XmlFormatter
So at this point, the complete code of the WebApiConfig.cs is given below.
using System.Net.Http.Headers; using System.Web.Http; using System.Web.Http.Dispatcher; using WebAPIVersioning.Custom; namespace WebAPIVersioning { public static class WebApiConfig { public static void Register(HttpConfiguration config) { config.MapHttpAttributeRoutes(); //Replacing default controller selector to our custom controller selector config.Services.Replace(typeof(IHttpControllerSelector), new CustomControllerSelector(config)); //Defineing the default route config.Routes.MapHttpRoute( name: "DefaultRoute", routeTemplate: "api/{controller}/{id}", defaults: new { id = RouteParameter.Optional } ); //Adding the custom media type to the JsonFormatter config.Formatters.JsonFormatter.SupportedMediaTypes .Add(new MediaTypeHeaderValue("application/vnd.dotnettutorials.employees.v1+json")); config.Formatters.JsonFormatter.SupportedMediaTypes .Add(new MediaTypeHeaderValue("application/vnd.dotnettutorials.employees.v2+json")); //Adding the custom media type to the XmlFormatter config.Formatters.XmlFormatter.SupportedMediaTypes .Add(new MediaTypeHeaderValue("application/vnd.dotnettutorials.employees.v1+xml")); config.Formatters.XmlFormatter.SupportedMediaTypes .Add(new MediaTypeHeaderValue("application/vnd.dotnettutorials.employees.v2+xml")); } } }Now build the solution and issue a request by specifying that you want the data in XML format and you will get the data as expected as shown below.
In the next article, I am going to discuss How to Enable SSL in Visual studio Development Server with example. Here, in this article, I try to explain how to implement Web API Versioning Using Custom Media Types step by step with an example. I hope this article will help you with your needs. I would like to have your feedback. Please post your feedback, question, or comments about this article.
Summary:
I hope this post will be helpful to understand how to configure Web API Versioning Using Custom Media Types
Please share this post with your friends and colleagues.
For any queries please post a comment below.
Happy Coding 😉
0 comments:
Post a Comment
If you like this website, please share with your friends on Facebook, Twitter, LinkedIn.