Introducing the ASP.NET Web API Help Page (Preview)
Today, following the announcement of the official release for ASP.NET Web API , we also released a preview for the ASP.NET Web API Help Page, which is available as a NuGet package. This package automatically generates help page content for Web APIs on your site. Visitors to your help page can use this content to learn how to call your web APIs. Everything generated by the help page is fully customizable using ASP.NET MVC and Razor.
Here is a quick intro video to get you started.
In the next few weeks I’m planning to publish a series of blog posts that will cover the following help page scenarios:
Part 1: Basic Help Page customizations
Changing the help page URI
Providing API documentations
Customizing the view
Part 2: Providing custom samples on the Help Page
Setting custom sample objects
Setting the samples when the action returns an HttpResponseMessage
Part 3: Advanced Help Page customizations
Adding additional information to the HelpPageApiModel
Creating new sample display templates
Give it a try and play with the help page preview package. We would love to hear your comments and feedbacks.
Thanks,
Yao
Comments
Anonymous
August 15, 2012
What is needed to get this to work with a WebApi service hosted via HttpSelfHostServer?Anonymous
August 15, 2012
Cool, does it work with custom routes aswell?Anonymous
August 16, 2012
@fedak Basically you'll need to generate the HTML without using MVC. I'm going to explain that on a different blog post in the next couple days. @Jonas Yup, it should work with custom routes.Anonymous
August 17, 2012
Great tool! It's open souce? Because i would to fork it and port to use Twitter Bootstrap. Thanks!Anonymous
August 17, 2012
@Dervanil Junior Yes, it's available on CodePlex now: aspnetwebstack.codeplex.com/.../897bf750a622Anonymous
August 22, 2012
Hi Yao, I installed the ASP.NET Web API Help Page, and noticed that after doing so my Route object no longer has any DataTokens, including the namespaces. Route r; r = routes.MapHttpRoute( name: "HelloWorld v1.0", routeTemplate: "helloworld/v1.0/{controller}/{id}", defaults: new { id = RouteParameter.Optional } ); r.DataTokens["Namespaces"] = new string[] { typeof(API.Controllers.HelloWorld.v1_0.GetStartedController).Namespace }; The above code use to work but now I'm getting a NullReferenceException. This is the typical solution most developers are using right now to define namespaces for the API routes. NickAnonymous
August 24, 2012
@Nick The Help Page should not have any effect on Web API routes. By any chance, were you using earlier version of Web API and got upgraded when installing the Help Page?Anonymous
August 27, 2012
are there plans to create something like WADL with the help pages api?Anonymous
August 28, 2012
Is there any attribute that can be used to document the data annontations which are placed on the parameters of an action?Anonymous
August 28, 2012
Hi I return a HttpResponseMessage in my function. The help page doesn't seem to handle that. I don't get any detailed response information or examples generated. Is there something I can do about this or is it a known issue? public HttpResponseMessage Get(int id) { var p = new Product{ Id = 1, Name = "Test"}; return Request.CreateResponse(HttpStatusCode.OK, p); } -MagnusAnonymous
August 29, 2012
It doesn't works with AttributeRouting because of this: github.com/.../86Anonymous
August 29, 2012
@Fred, currently we don't have any plan to generate WADL using the help page API. You can consider using ApiExplorer to create WADL-like metadata. @Grahame Horner, there isn't any built-in attribute but you should be able to define your own attribute and access it through ApiDescription.ActionDescriptor.GetCustomAttributes or ApiParameterDescription.ParameterDescriptor.GetCustomAttributes. Note that ApiDescriptions are returned by ApiExplorer. @Magnus, yes, you can use the provided extension method "SetActualResponseType" to hint what's being return in the HttpResponseMessage. E.g. config.SetActualResponseType(typeof(Product), "YourController", "Get", "id"); *config is an instance of HttpConfigurationAnonymous
August 31, 2012
Thank you, very nice! When I click in to se the Response Information I only gets this kind of messages for all formats, the application/json, text/json, application/xml and text/xml.. ? Do you know what to do..? An exception has occurred while using the formatter 'JsonMediaTypeFormatter' to generate sample for media type 'application/json'. Exception message: Ett eller flera fel har uppstått. An exception has occurred while using the formatter 'JsonMediaTypeFormatter' to generate sample for media type 'text/json'. Exception message: Ett eller flera fel har uppstått. An exception has occurred while using the formatter 'XmlMediaTypeFormatter' to generate sample for media type 'application/xml'. Exception message: Ett eller flera fel har uppstått. An exception has occurred while using the formatter 'XmlMediaTypeFormatter' to generate sample for media type 'text/xml'. Exception message: Ett eller flera fel har uppstått. Thank you /MattiasAnonymous
September 05, 2012
Hi Yao, Thanks very much for this, setting up your project was fairly straightforward once I updated my solution to use RTW packages. I've got a question regarding the comments on methods returning HttpResponseMessage though. Setting up the custom sample data was easy enough with config.SetActualResponseType(typeof(MyCustomType), "MyController", "Get"); However, the XML comments decorating the method are not getting picked up for the standard "description". Does this require some additional configuration as well? Thanks again, JaumeAnonymous
September 06, 2012
Hi Yao, Please disregard my comment above, the descriptions are getting picked up just fine. My issues was that I had a typo in my ///summary clauses, which was ultimately creating malformed XML. Thanks, JaumeAnonymous
September 09, 2012
Hi Yao, This looks like a great start. Some suggestions (sorry if there are quite a few but I would love to see your work become part of the product and i wasn't sure where else to submit ideas):
- If an action has an enum parameter, you could list the options and use the XML comment on each enum value to describe the option.
- The parameters table could have a "Default" column to indicate what the default value is for any parameter that has a default
- Is it possible to generate and create a link to an XSD for the request/response XML format
- It might be nice to either allow for multiple manually created samples with some descriptive text or allow for formatting within the sample string.
- a client side test harness built in to the help page would allow the user to try the API out directly
- To my mind, ideally this documentation would be "inline" with the actual API (i.e. from your example /api/users would be the API and /api/users?format=help would give the help page for part of the API)... the help page could then also contain the representation from the current resource.
- Could your samples include comments derived from the Xml Documentation for the objects being submitted / retrieved? So for your example, the sample might be: <User> <!-- The name of the user --> <Name>sample string 1</Name> ... </User>
- If not required, can the sample XML not contain xmlns:xsi="www.w3.org/.../XMLSchema-instance" xmlns:xsd="www.w3.org/.../XMLSchema". To do this, you neeed to call the XmlSerializer with a blank namespace: var xmlSerializerNamespaces = new XmlSerializerNamespaces(); xmlSerializerNamespaces.Add(String.Empty, defaultNamespace); xmlSerializer.Serialize(xmlWriter, objectToBeSerialised, xmlSerializerNamespaces); where defaultNamespace should be either string.Empty or the value of the XmlRootAttribute's Namespace property if the root object has this attribute.
- In the case of the actions having an Authorize attribute, could the help check whether the current user would be able to use the action before documenting it? Piers
Anonymous
September 14, 2012
Couple of Documentattion tags are not working. returns example Also how do I show the link to sample url which user click to run a sample.?Anonymous
September 14, 2012
How do I leverage using this Help doc to display information for Return data class?Anonymous
September 20, 2012
I was wondering when you are going to put the next part of this series?Anonymous
September 25, 2012
Is there any sample where I can create my own implementation for IApiExplorer? Since I need to support versioning in my uri (eg: api/v1/products/123). Currently the GetApiExplorer() method doesn't return any api descriptions for the URI that I previously mentioned. I would appreciate if you provide me with any directions to solve the above mentioned problem.Anonymous
September 28, 2012
I've run into a problem with API eplorer, All works fine while it enumerates over my controllers, however : When evaulating a Controller : ApiController - all methods show up, When evaluating a Controller : MyCustomController<T> - only GET methods show up (where T : IUnitOfWork) - I'm using Mindscape Lightspeed as my ORM.Anonymous
September 30, 2012
@MattiasSorry for the late reply, for now can you change the following in HelpPageSampleGenerator.cs to display the full exception message? sample = new InvalidSample(String.Format( CultureInfo.CurrentCulture, "An exception has occurred while using the formatter '{0}' to generate sample for media type '{1}'. Exception message: {2}", formatter.GetType().Name, mediaType.MediaType, e.Message <== change this to e.ToString())); @Piers LawsonThanks for the suggestions. Feel free to submit your ideas on aspnetwebstack.codeplex.com/.../basic. @KingAnil2010Currently it doesn't support returns tag but we'll consider adding the support. Sorry I didn't undertand your question about "link to sample url", can you elaborate? What kind of information are you looking to display on the return data class? Can you give me an example? @Sancho OreSorry I was away on vacation but will post the series as soon as possible. @Chandra RYou can register your CustomApiExplorer through config (HttpConfiguration): config.Services.Replace(typeof(IApiExplorer), new CustomApiExplorer()); you can look at the default ApiExplorer implementation for reference: aspnetwebstack.codeplex.com/.../10f94d855cc9 @MaciekI couldn't repro what you described with the following controllers. Can you share your controllers? (feel free to upload a repro on SkyDrive or something) public class CustomController<T> : ApiController { public int Get(T a) { return 0; } public void Post(T a) { } } public class CustomIntController : CustomController<int> { public int Post() { return 0; } }Anonymous
October 01, 2012
Great article, Waiting in part 2 particularly on 'Setting the samples when the action returns an HttpResponseMessage' which i use a lot.Anonymous
October 01, 2012
Found out how to 'Setting the samples when the action returns an HttpResponseMessage' Use the following in Helpage.config/Register Method //// The sample will be generated as if the controller named "Values" and action named "Post" were returning YourType. config.SetActualResponseType(typeof(YourType), "Values", "Post");Anonymous
October 10, 2012
I am taking an object as input parameter such as public string GetData([FromUri]Product product) { //..... } But while generating the help page i want to include the properties of product class. Is it possible??Anonymous
October 11, 2012
@Rahul By default, it doesn't display the properties. However you can add some extra logic to the "GenerateApiModel" method in HelpPageConfigurationExtensions.cs to handle this case. Here is rough code snippet just to give you an idea: gist.github.com/c231426e036421d4dc78Anonymous
October 19, 2012
Does someone know it works on Azure? Deployed it to Azure and got a yellow screen of death. Haven't testedany further, was late friday afternoon, but I think it is a right problem.Anonymous
October 19, 2012
@Broersa It does work on Azure. I have a sample deployed here: webapisample.azurewebsites.net/Help In case you are using XML documentation file, make sure you include it in the project and enable "Copy to Output Directory". Hope this helps, YaoAnonymous
October 21, 2012
@Yao It was indeed the xml file that didn't get copied. Works like a charm now.Anonymous
October 29, 2012
Yao, thanks for this package. It works great for most use cases! However, it has problems with controllers with generic types.
- In XmlDocumentationProvider.GetMemberName you use method.DeclaringType.FullName. This produces a string that contains the concrete types of the generic type parameters. A combination of method.DeclaringType.Namespace and method.DeclaringType.Name produces the correct class name.
- Methods on those generic types that don't have generic parameters themselves but use a generic parameter from the class as parameter type will result in a member name in the XML doc file that doesn't contain a parameter type but simply a reference to the generic type argument of the class, e.g. `0. I haven't found a fix for this yet. Please also see stackoverflow.com/.../how-to-get-methodinfo-for-open-generic-type-from-methodinfo-of-closed-type
Anonymous
October 30, 2012
Hi, i am having trouble getting it to work. I have followed the video but are not getting the info for the controllers. I get the "empty" help page, where only the hardcoded stuff is shown. It's like it can´t se my Web Api controllers. Any thoughts on how I can fix this?Anonymous
October 30, 2012
The comment has been removedAnonymous
October 30, 2012
@Daniel Hilgarth: Yup, it is as if none of my controllers is getting noticed by help page. All the stuff in the video i have done. Got it working on a test project that i set up in same way as the real one, and that one works. I´m trying to debug at the moment, but i am getting nowhere, unfortunately.Anonymous
October 30, 2012
@Thomas C: Set a break point in the XmlDocumentationProvider to verify if it gets hit. If not, there is still something wrong with your configuration. I still think that is your problem, because if the XmlDocumentationProvider doesn't find your XML file, you will get an exception when trying to view the help page. And when it does find the find XML file but doesn't find documentation for one particular method, it would still display your controller and its actions.Anonymous
October 30, 2012
@Daniel Hilgarth: It hits and parses without any problem. But i still get no output in the view.Anonymous
October 30, 2012
@Daniel Hilgarth Thanks for letting me know about the issue, Daniel. Please feel free to report it on our codeplex site ( aspnetwebstack.codeplex.com/.../basic) This will help us keep track of the issue so that we can address it in a future iteration. @Thomas C Thomas, it would be great if you can share a simple repro so that more folks can help out. From your description, it seems like ApiExplorer is not returning any ApiDescriptions for some reason. Put a breakpoint in the HelpController.Index and see if that's actually the case.Anonymous
October 30, 2012
The comment has been removedAnonymous
October 30, 2012
The comment has been removedAnonymous
October 31, 2012
@Thomas C I think there's a small issue with the route parameters. I see you have the route "api/{controller}/{action}/{id}/{folderID}/{projectID}/{queryDate}" where all parameters except {controller} have the RouteParameter.Optional as the default. Eventhough your intention is to have them as optionals the reality is that they are not if they come before the action parameter. Take the following action in your "Project" controller for example: Get(int folderID) In this case, one might think "api/Project/Get/6" would be the URL for it where {folderID}=6. But in reality this translate into {controller}=Project, {action}=Get, {id}=6. The actual URL for the action above is "api/Project/Get/5/6" where {controller}=Project, {action}=Get, {id}=5, {folderID}=6. Therefore can you try changing the action to Get(int id, int folderID) and see if it works? Here is another idea if the parameters are not required to be on the URL path - get them as query strings. You can change the route to "api/{controller}/{action}" and the URL for the above action would be "api/Project/Get?folderID=6" instead of "api/Project/Get/5/6". Notice that you don't need to add the extra 5 as {id} anymore. Hope this helps, YaoAnonymous
November 02, 2012
Perhaps this is not best practice, but we are using a controller to do a file upload, where we use: var myFile = HttpContext.Current.Request.Files["myFile"]; and I have no way of indicating that this is a required peice of data to be passed in via a file <input> in the form post. I tried adding a [Frombody] parameter for the file, but couldn't find the correct syntax. Meanwhile if I add a <param name="myFile">The file expected to be uploaded in the request</param> it doesn't show on the help detail page because it's not a real parameter. Perhaps something could be added that would allow me to add a 'Other Requirements' row to the parameters list?Anonymous
November 03, 2012
@t_elsmore You can try creating a custom attribute to specify the 'Other Requirements' and add it to the parameter list in HelpPageConfigurationExtensions.cs. Here is rough code snippet to give you an idea: gist.github.com/42d5e9c0fa9dd9e3bf30Anonymous
November 05, 2012
@Yao Thanks for youre suggestions. I have modified them to work with the Api the way I intended and it works like a charm :-) I now have another problem, I don´t get any Response Information generated for the ones where I return a HttpResponseMessage. Is there a way to fix this? Thanks again!Anonymous
November 06, 2012
@Thomas C Glad to hear that it's working for you now :) Yes. For actions returning HttpResponseMessage please see part 2 of this series: blogs.msdn.com/.../asp-net-web-api-help-page-part-2-providing-custom-samples-on-the-help-page.aspxAnonymous
November 08, 2012
Any thoughts on how this might leverage, merge with Swagger? http://swagger.wordnik.com/Anonymous
November 17, 2012
I have a problem. im working with routes.MapHttpRoute( name: "ActionApi", routeTemplate: "api/{controller}/{action}/{id}", defaults: new { id = RouteParameter.Optional, action = "" } ); in some call the action are "" because im calling to the root then i got this error The route template separator character '/' cannot appear consecutively. It must be separated by either a parameter or a literal value. Parameter name: routeTemplate i think its because the action "Configuration.Services.GetApiExplorer().ApiDescriptions" cannot build the correct route can you give me a choice?????? or can you fix it????????????Anonymous
December 02, 2012
@Colin Bowern You can checkout the ApiExplorer (blogs.msdn.com/.../asp-net-web-api-introducing-iapiexplorer-apiexplorer.aspx). It's more suitable for that scenario. @francisco Unfortunately I cannot repro your issue with the route you provided. Can you open an issue on aspnetwebstack.codeplex.com/.../basic and attach a simple repro? Thanks, YaoAnonymous
February 21, 2013
Is this supposed to work with WebForms? I created a simple set of API's. The API's work perfectly fine - returning the right results. BUT I cannot get the Help Page. I have installed "Microsoft.AspNet.WebApi.HelpPage"Anonymous
February 26, 2013
Hi Sam, Can you try the steps from the following blog post about using help page on web forms? blogs.msdn.com/.../enabling-asp-net-web-api-help-pages-for-asp-net-web-forms-applications.aspx. Let me know if it worked for you. Thanks, YaoAnonymous
March 07, 2013
Hi, i have some entitysetcontrollers is it possible to display them in the help page aswell?Anonymous
March 12, 2013
Hi Erik, Currently the Help Page doesn't support entitysetcontrollers by default because our OData implementation uses different routing mechanism. However, we might consider providing the support in the future.Anonymous
June 16, 2013
Are there any issues with using StructureMap and the WebApi help page? I created an empty WebApi project, and added StructureMap.MVC4. When I browse to the API link, I get the exception Activation error occured while trying to get instance of type HelpController, key "" with an inner exception StructureMap Exception Code: 202nNo Default Instance defined for PluginFamily System.Web.Http.HttpRouteCollection, System.Web.Http but if I hit continue the page does appear.Anonymous
July 22, 2013
Yao, is there anywhere where I can 'vote' to add support for entitysetcontroller to this?Anonymous
November 18, 2013
The comment has been removedAnonymous
January 07, 2015
how to use help pages with MultipartFormDataStreamProvider