5

I'm trying to use SwaggerUI, but I'm having some problems.
When I call http://mysite.com/api/swagger I get this:

{
    "apiVersion":"4.0.0.0",
    "swaggerVersion":"2.0",
    "basePath":"http://mysite.com",
    "resourcePath":null,

    "apis":
        [
            {
                "path":"/api/docs/V1.Foo",
                "description":"Foo V1.",
                "operations":[]
            },
            {
                "path":"/api/docs/V2.Foo",
                "description":"Foo V2.",
                "operations":[]
            }
        ]
}

But, when I call http://mysite.com/api/docs/V1.Foo or http://mysite.com/api/docs/V2.Foo I get this:

<Error>
    <Message>
    The requested resource does not support http method 'GET'.
    </Message>
</Error>

It look like I'm calling my API, but I'm trying to get the API documentation.

All my controllers implement System.Web.Http.ApiController.

This is my WebApiConfig:

public static class WebApiConfig
{
    public static void Register(HttpConfiguration config)
    {
        RouteTable.Routes.IgnoreRoute("{resource}.axd/{*pathInfo}");

        config.Routes.MapHttpRoute(
            name: "SwaggerApi",
            routeTemplate: "api/docs/{controller}",
            defaults: new { swagger = true }
            );

        config.Routes.MapHttpRoute(
            name: "Swagger",
            routeTemplate: "api/swagger",
            defaults: new { controller = "swagger" }
        );


        config.Routes.MapHttpRoute(
            name: "DefaultApi",
             routeTemplate: "api/{version}/{controller}/{id}",
             defaults: new { id = RouteParameter.Optional, version = "v1" }
            );

        config.Filters.Add(new SwaggerActionFilter());

        try
        {
            config.Services.Replace(typeof(IDocumentationProvider),
                new XmlCommentDocumentationProvider(HttpContext.Current.Server.MapPath("~/bin/XmlDocument.XML")));
        }
        catch (FileNotFoundException)
        { }

        //My version selector
        config.Services.Replace(typeof(IHttpControllerSelector), new VersionControllerSelector(config));
        config.Filters.Add(new VersionNoHeaderAttribute());
    }
}

And this is my IHttpControllerSelector implementation (VersionControllerSelector):

...

public HttpControllerDescriptor SelectController(HttpRequestMessage request)
{
    var routeData = request.GetRouteData();

    if (routeData == null)
    {
        throw new HttpResponseException(HttpStatusCode.NotFound);
    }

    string version;

    if (GetRouteVariable<bool>(routeData, "swagger"))
    {
        version = ""; // Here I have the version and controller name.
    }
    else if (request.RequestUri.ToString().ToLower().EndsWith("swagger"))
    {
        version = "net."; // Net.Swagger
    }
    else
    {
        version = GetRouteVariable<string>(routeData, VersaoKey);

        if (version == null)
        {
            throw new HttpResponseException(HttpStatusCode.NotFound);
        }

        version = string.Format(CultureInfo.InvariantCulture, "{0}.", version); // V1.MyControler
    }

    var controllerName = GetRouteVariable<string>(routeData, ControllerKey);

    if (controllerName == null)
    {
        throw new HttpResponseException(HttpStatusCode.NotFound);
    }

    var key = version + controllerName;

    HttpControllerDescriptor controllerDescriptor;

    if (_controllers.Value.TryGetValue(key, out controllerDescriptor))
    {
        return controllerDescriptor;
    }

    throw new HttpResponseException(HttpStatusCode.NotFound);
}

...

SwaggerActionFilter doesn't get my request when I call http://mysite.com/api/docs/"some-controller".
If I use SwaggerUI in another Solution without versioning, I'm able to get all documentations.

I know that maybe my versioning selector is wrong, but I dont't know what is wrong.

4

0 回答 0