7

我正在尝试在我的后端系统中添加 API 文档。默认 ApiExplorer 和帮助页面在我将版本引入我的 Api 控制器之前工作得非常好。

为了添加版本,我在 Controllers 文件夹下创建了子文件夹:

  • v1
  • v2
  • v3

并在那里有基于版本的 Api 控制器。为了让我的 Api 可被发现,我必须重写 DefaultHttpControllerSelector 以考虑任何客户端提供的命名空间并将它们映射到正确的控制器:

这破坏了我的默认 ApiExplorer,以下属性返回零 api 描述

Configuration.Services.GetApiExplorer().ApiDescriptions

如何自定义现有的 ApiExplorer 并帮助他找到我的 Api 控制器而不是重写整个 ApiExplorer 实现。我真的只需要显示在哪里可以找到我的 Api 控制器。

请指教。

4

3 回答 3

8

我会告诉你一个方法来做到这一点。此代码仅供学习。在这里,我不是在谈论设计和最佳实践,所以请随意更改您想要的任何内容。

好吧,您必须按照以下步骤操作:

1)创建自定义ApiExplorer:

public class MyApiExplorer: ApiExplorer
{
    private readonly string _version;

    public MyApiExplorer(string version) : base(GlobalConfiguration.Configuration)
    {
        _version = version != null ? version.ToUpperInvariant() : "V1";

        foreach(var apiDescription in ApiDescriptions)
        {
            apiDescription.RelativePath = apiDescription.RelativePath.Replace("{version}", _version);
        }

    }

    public override bool ShouldExploreController(string controllerVariableValue, HttpControllerDescriptor controllerDescriptor,
        IHttpRoute route)
    {
        return controllerDescriptor.ControllerType.FullName.Contains(_version);
    }

}

a) 在构造函数中,_version 将被转换为大写字母(以防万一它作为小写字母传递),但如果它为空,那么它将采用 V1 作为默认值。然后更改相对路径以显示特定版本而不是 {version}。

b) ShouldExploreController(简而言之)决定是否将特定控制器显示在文档中。在这种情况下,我们将只向控制器显示其类型全名包含所选版本。

2) 转到 HelpController 类并更改 Index 方法,如下所示:

public ActionResult Index(string version)
{
    //...

    Configuration.Services.Replace(typeof(IApiExplorer), new MyApiExplorer(version));

    return View(Configuration.Services.GetApiExplorer().ApiDescriptions);
}

我们正在用自己替换当前的 ApiExplorer,以便在调用 Configuration.Services.GetApiExplorer() 时返回

现在您可以使用此 .../help?version=v1 或 .../help?version=v2 或 .../help?version=v3 ,您将获得特定的 api 控制器文档。

于 2015-04-07T23:18:50.483 回答
6

原来和ApiExplorer没有关系。相反,您应该修改基于命名空间的控制器选择器:

NamespaceHttpControllerSelector : DefaultHttpControllerSelector
{
//...
    public override IDictionary<string, HttpControllerDescriptor> GetControllerMapping() 
    {
        var mapping = base.GetControllerMapping();
        mapping["User"] = new HttpControllerDescriptor
        {
            Configuration = _httpConfig,
            ControllerName = "User",
            ControllerType = typeof(UserController)
        };
        //...
        return mapping;
    }
    //...  }

那是。之后,默认的 ApiExplorer 将找到您的控制器并获取所有操作。

于 2014-02-24T16:50:19.960 回答
1

我最近遇到了类似的问题,并用这个解决了我的问题:2 LOC:

public class VersionControllerSelector : IHttpControllerSelector

public class VersionControllerSelector : DefaultHttpControllerSelector

...和...

public VersionControllerSelector(HttpConfiguration config)

public VersionControllerSelector(HttpConfiguration config) : base(config)
于 2014-04-15T17:46:34.717 回答