All the help page samples I’ve shown you so far are pretty much generated at runtime, meaning the help page is generated after you start the application. Today, I’m going to show you that it doesn’t always need to be generated at runtime. In fact, it can be generated at design-time. Yes, before you host and start the application!

This is especially useful when you want to provide any kind of tooling for Web API. E.g. generating proxies for your Web APIs as part of the build process. Another scenario that can benefit from this is when you want to host the help page separately from your application – you can simply generate the help page as HTML files and then host the generated files anywhere that supports HTML.

To show you how this can be done, I’ve created a simple command-line utility (WebApiHelpPageGenerator.exe) that will statically generate the help page as HTML files. All you need to provide is the path to you application assembly.

The source code can be downloaded at: http://code.msdn.microsoft.com/Design-time-help-page-3048fb43

The binaries can be downloaded at: WebApiHelpPageGenerator.zip

Using the WebApiHelpPageGenerator.exe

The WebApiHelpPageGenerator.exe takes one required parameter (-p) which is the path to your application assembly.

WebApiHelpPageGenerator.exe -p MvcApplication1.dll

You do need to follow a convention in order to opt-in: Having a public static “WebApiConfig” class with a static “Register” method where the API routes are specified. This is the pattern that we have in the default Web API templates.

public static class WebApiConfig
{
    public static void Register(HttpConfiguration config)
    {
        config.Routes.MapHttpRoute(
            name: "DefaultApi",
            routeTemplate: "api/{controller}/{id}",
            defaults: new { id = RouteParameter.Optional }
        );
    }
}

If everything goes well, you will see the following HTML files generated.

image

You can open the HTML files and even browse through them locally.

image

Clicking on “GET api/Values” will take you to the “GET-api-values.html”.

image

Including Controllers from different assembly

Very often you can have the controllers defined on different assemblies. In order to get all of them, simply use the -r flag.

WebApiHelpPageGenerator.exe -p MvcApplication1.dll –r ControllerLibrary1.dll ControllerLibrary2.dll

image

Generating proxy or other types of documentation

You can extend the WebApiHelpPageGenerator.exe to generate proxy/client or other types of documentation.

To do this, first you need to add the reference to WebApiHelpPageGenerator.exe.

image

Then, implement the IOutputGenerator. For illustration, I simply printed things out to the console but you can use any templating engine to generate the documentation and save it to files.

using System;
using WebApiHelpPageGenerator;
 
namespace MyExtension
{
    public class MyOutputGenerator : IOutputGenerator
    {
        public void GenerateIndex(System.Collections.ObjectModel.Collection<System.Web.Http.Description.ApiDescription> apis)
        {
            Console.WriteLine("Generating index.");
        }
 
        public void GenerateApiDetails(WebApiHelpPage.Models.HelpPageApiModel apiModel)
        {
            Console.WriteLine("Generating something for {0}", apiModel.ApiDescription.ID);
        }
    }
}

Next, just use the -e option to load the assembly where the custom IOutputGenerator is defined.

WebApiHelpPageGenerator.exe -p MvcApplication1.dll -e MyExtension.dll

image

 

Update

I’ve implemented a custom IOutputGenerator that will generate a simple JavaScript client. You can download the binary here: WebApiJsClientGenerator.zip

To try it, simply use the -e option.

WebApiHelpPageGenerator.exe -p MvcApplication1.dll -e WebApiJsClientGenerator.dll

It will spit out a file that look like this:

   1: function GetUsers(id) {
   2:     return $.ajax({
   3:         url: "/api/Users/" + id,
   4:         type: "GET"});
   5: }
   6:  
   7: function PostUsers(user) {
   8:     return $.ajax({
   9:         url: "/api/Users",
  10:         type: "POST",
  11:         contentType: "application/json",
  12:         data: JSON.stringify(user)});
  13: }
  14:  
  15: function GetValues() {
  16:     return $.ajax({
  17:         url: "/api/Values",
  18:         type: "GET"});
  19: }
  20:  
  21: function GetValues1(id) {
  22:     return $.ajax({
  23:         url: "/api/Values/" + id,
  24:         type: "GET"});
  25: }
  26:  
  27: function PostValues(value) {
  28:     return $.ajax({
  29:         url: "/api/Values",
  30:         type: "POST",
  31:         contentType: "application/json",
  32:         data: JSON.stringify(value)});
  33: }
  34:  
  35: function PutValues(id, value) {
  36:     return $.ajax({
  37:         url: "/api/Values/" + id,
  38:         type: "PUT",
  39:         contentType: "application/json",
  40:         data: JSON.stringify(value)});
  41: }
  42:  
  43: function DeleteValues(id) {
  44:     return $.ajax({
  45:         url: "/api/Values/" + id,
  46:         type: "DELETE"});
  47: }

* If you’re getting error like “Could not load file or assembly…”, it means that the WebApiJsClientGenerator.dll file is blocked. To unblock it, go to file Properties and click Unblock. After that, the error should go away.

image

 

Enjoy!

Yao