ASP.Net Web Api - ApiExplorer does not contain any ApiDescriptions
Asked Answered
P

3

14

I am trying to implement an Options method in a controller of my web service that will return a message containing the valid HTTP methods for the URI endpoint associated with the controller. My Options method looks something like this:

public HttpResponseMessage Options()
{
    var resp = new HttpResponseMessage();
    resp.Content = new StringContent("");

    var apiExplorer = GlobalConfiguration.Configuration.Services
        .GetApiExplorer();

    foreach (ApiDescription api in apiExplorer.ApiDescriptions)
    {
        resp.Content.Headers.Add("Allow", api.HttpMethod.Method);
    }

    return resp;
}

I have tried the above method in a brand-new Web Api project (implication: unaltered routing) inside of a controller with Get, Post, and Delete methods. As expected, a response with "Allow: GET, POST, DELETE" is returned. I am having trouble, however, adding this to a larger project that I am working on. In the larger project, the ApiDescriptions list within ApiExplorer does not contain any elements. Why is this? I suspect it is due to the custom routing that has been implemented, although the only basis for that suspicion is the following link:

http://forums.asp.net/t/1821651.aspx/1

Has anybody else experienced this empty ApiDescription list? If so, did you find a remedy?

Note: I am using MCV 4 RC

Phillane answered 16/8, 2012 at 18:35 Comment(3)
I'm having the same issue, and my project does have some weird routing. I temporarily set the routing back to the scaffold default, and I got the collection populated. Even the help page described in @PaigeCook's answer worked fine after that. Of course I can't do that in production, but at least I can generate the documentation and put it somewhere.Ignacia
A team member of mine expanded on the question in the asp.net forums (forums.asp.net/t/1835575.aspx/…), and it turns out to be a known bug. We ended up finding the code for ApiExplorer somewhere on GitHub, customizing it a bit, and eliminating the error that occurred in our circumstances.Phillane
Cool. I don't suppose you gave them a pull request? :)Ignacia
D
3

If you use Glimpse, you might have to disable it's route inspector:

<glimpse defaultRuntimePolicy="On" endpointBaseUri="~/Glimpse.axd">
  <logging level="Off" />
  <tabs>
    <ignoredTypes>
      <add type="Glimpse.AspNet.Tab.Routes, Glimpse.AspNet" />
    </ignoredTypes>
  </tabs>
  <inspectors>
    <ignoredTypes>
      <add type="Glimpse.AspNet.Inspector.RoutesInspector, Glimpse.AspNet" />
    </ignoredTypes>
  </inspectors>
</glimpse>

Glimpse creates RouteProxies that break enumeration in HostedHttpRouteCollection: https://github.com/mono/aspnetwebstack/blob/master/src/System.Web.Http.WebHost/Routing/HostedHttpRouteCollection.cs

I know the link is for mono but the same is true for standard .Net.

Destroyer answered 4/3, 2016 at 9:31 Comment(1)
Thank you so much for your answer. That was the problem I was facing.Chemoprophylaxis
A
2

The solution for this problem is to comment in ProjectName\Areas\HelpPage\Controllers\HelpController.cs the constructors like this:

    public class HelpController : Controller
        {
            private const string ErrorViewName = "Error";

    //        public HelpController()
    //            : this(GlobalConfiguration.Configuration)
    //        {
    //        }

    //        public HelpController(HttpConfiguration config)
    //        {
    //            Configuration = config;
    //        }

            /// <summary>
            /// GlobalConfiguration By default
            /// </summary>
            protected static HttpConfiguration Configuration
            {
                get { return GlobalConfiguration.Configuration; }
            }

            public ActionResult Index()
            {
                ViewBag.DocumentationProvider = Configuration.Services.GetDocumentationProvider();
                return View(Configuration.Services.GetApiExplorer().ApiDescriptions);
            }
....

The default constructor is not called;

The second method is to inject the default constructor by add this attribute [InjectionConstructor] on default constructor like this:

public class HelpController : Controller
    {
        private const string ErrorViewName = "Error";

         [InjectionConstructor]
        public HelpController()
            : this(GlobalConfiguration.Configuration)
        {
        }

        public HelpController(HttpConfiguration config)
        {
            Configuration = config;
        }

        /// <summary>
        /// GlobalConfiguration By default
        /// </summary>
        protected static HttpConfiguration Configuration { get; private set; }
....
Andresandresen answered 23/5, 2014 at 13:25 Comment(3)
I tried both the suggested methods, they do not work.Pedo
Do you use Glimpse for any chance? The generated route proxies break iteration over HostedHttpRouteCollection. Take a look at GetEnumerator() github.com/mono/aspnetwebstack/blob/master/src/…Destroyer
@AxelWilczek probably this was my problem.Andresandresen
R
1

You should look to upgrade to the RTM of WebApi that was released yesterday and then check out the newly released ASP.NET WebApi Help Page (Preview) that was also released yesterday.

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.

It is implementing the ApiExplorer under the covers.

Rappel answered 16/8, 2012 at 19:46 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.