Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I get ASP.NET Web API working with versioning and the Help Page extension?

Tags:

I've implemented a versioning framework into my WebAPI application, and would very much like to get it working with the new Help Page extension from Microsoft.

Microsoft.AspNet.WebApi.HelpPage

SDammann.WebApi.Versioning

Quite simply, I don't know how to get them both working together. I have 2 projects:

  • AdventureWorks.Api (The main host/root application)
  • AdventureWorks.Api.v1 (A class library containing the first version of the API)

The versioning works as expected.

I've tried installing the HelpPage package on the root application, and when I browse to the help page, it appears none of the controllers are being found. Internally I believe it uses:

Configuration.Services.GetApiExplorer().ApiDescriptions 

This returns no results, so I get an error.

Can anyone assist me in getting both of these packages working together?

Edit: In the beginning, I wasn't sure this was a routing problem, but recent comments seem to suggest otherwise. Here is my RouteConfig.cs

public class RouteConfig {     public static void RegisterRoutes(RouteCollection routes)     {         routes.IgnoreRoute("{resource}.axd/{*pathInfo}");          routes.MapHttpRoute(             name: "SldExportAliasApi",             routeTemplate: "api/v{version}/sld-export/{id}",             defaults: new { id = RouteParameter.Optional, controller = "Export" }         );          routes.MapHttpRoute(             name: "LinkRoute",             routeTemplate: "api/v{version}/link/{system}/{deployment}/{view}",             defaults: new { controller = "Link" }         );          routes.MapHttpRoute(              name: "DefaultSubParameterApi",              routeTemplate: "api/v{version}/{controller}/{id}/{param}",              defaults: new { id = RouteParameter.Optional, param = RouteParameter.Optional }         );          routes.MapHttpRoute(             name: "DefaultApi",             routeTemplate: "api/v{version}/{controller}/{action}/{id}",             defaults: new { action = "Index", id = RouteParameter.Optional }         );          routes.MapRoute(             name: "Default",             url: "{controller}/{action}/{id}",             defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }         );     } } 
like image 607
mortware Avatar asked Feb 12 '13 10:02

mortware


People also ask

Is versioning possible in asp net Web API?

As the application grows and business need increase, Versioning of the API is one of the difficult and important part of the API as it makes the API backward compatible. We can do Versioning in ASP.NET Web API with URI, QueryString, Custom Headers and Accept Header parameters, etc.

Which one from the following will run on top of ASP Net Web API help pages?

NuGet packages (36) A simple Test Client built on top of ASP.NET Web API Help Page.

How do I use versioning in .NET core API?

We've already set a name for the query string parameter (api-version) that we are going to use to send versioning information. We use the [ApiVersion("1.0")] attribute to set the version of the controller. We can see that all the strings starting with “B” are returned as a response.


2 Answers

You need to get a documentation XML file from your project AdventureWorks.Api.v1 project and place it in the bin folder of the AdventureWorks.Api project:

Then add these lines to your Application_Start method:

// enable API versioning         GlobalConfiguration.Configuration.Services.Replace(typeof(IHttpControllerSelector), new RouteVersionControllerSelector(GlobalConfiguration.Configuration));         GlobalConfiguration.Configuration.Services.Replace(typeof(IApiExplorer), new VersionedApiExplorer(GlobalConfiguration.Configuration));         GlobalConfiguration.Configuration.Services.Replace(typeof(IDocumentationProvider),                                 new XmlCommentDocumentationProvider(System.IO.Path.GetDirectoryName(                                     System.Reflection.Assembly.GetExecutingAssembly().GetName().CodeBase) +                                                                     "\\Adventure.Api.v1.XML")); 

Then you can view your API with the documentation.

Sometimes the version number does not get to be picked up correctly, and replaced by ???

To fix this add:

if (api.ActionDescriptor.ControllerDescriptor.ControllerType.Namespace != null)     {         var versionName = api.ActionDescriptor.ControllerDescriptor.ControllerType.Namespace.Replace(".Controllers", "").Split('.').Last();         api.RelativePath = api.RelativePath.Replace("v???", versionName);     } 

to your ApiGroup.cshtml exactly at this place:

@foreach (var api in Model) {     if (api.ActionDescriptor.ControllerDescriptor.ControllerType.Namespace != null)     {         var versionName = api.ActionDescriptor.ControllerDescriptor.ControllerType.Namespace.Replace(".Controllers", "").Split('.').Last();         api.RelativePath = api.RelativePath.Replace("v???", versionName);     }     <tr>         <td class="api-name"><a href="@Url.Action("Api", "Help", new { apiId = api.GetFriendlyId() })">@api.HttpMethod.Method @api.RelativePath</a></td>         <td class="api-documentation">         @if (api.Documentation != null)         {             <p>@api.Documentation</p>         }         else         {             <p>No documentation available.</p>         }         </td>     </tr> } 

This should do the trick!

like image 163
Hasan Salameh Avatar answered Oct 26 '22 22:10

Hasan Salameh


I couldn't figure out how to comment on a post :( I think this should probably be a comment under the marked answer for this question but SDamman is updated and all I needed to do was this

// enable API versioning                    GlobalConfiguration.Configuration.Services.Replace(typeof(System.Web.Http.Dispatcher.IHttpControllerSelector),       new SDammann.WebApi.Versioning.RouteVersionedControllerSelector(GlobalConfiguration.Configuration));  GlobalConfiguration.Configuration.Services.Replace(typeof(IApiExplorer), new SDammann.WebApi.Versioning.VersionedApiExplorer(GlobalConfiguration.Configuration)); 

There is a type called VersionedApiExplorer and it works great. Hope this helps the solution is much easier now.

EDIT: I realized after trying to get help working again myself that my answer wasn't obvious at all.

The ONLY thing you need to do to get help pages working is replace the global configs IApiExplorer, that's it. Just do it right after you change the handler per sdammans instructions.

like image 34
Paul Wade Avatar answered Oct 27 '22 00:10

Paul Wade