我正在尝试在我的后端系统中添加 API 文档。 默认 ApiExplorer 和帮助页面工作得非常好,直到我向我的 API 控制器引入版本为止。
为了添加版本,我在 Controllers 文件夹下创建了子文件夹:
并且有基于版本的 API 控制器。为了让我的 API 可以被发现,我必须重写
DefaultHttpControllerSelector
以考虑任何客户端提供的命名空间并将它们映射到正确的控制器:
这破坏了我的默认 ApiExplorer,并且以下属性返回零 api 描述
Configuration.Services.GetApiExplorer().ApiDescriptions
我如何定制现有的 ApiExplorer 并帮助他找到我的 Api 控制器而不是重写整个 ApiExplorer 实现。我真的需要展示在哪里可以找到我的 API 控制器。
请指教。
我将向您展示一种方法。这段代码仅供学习。这里我不谈论设计和最佳实践,所以请随意更改您想要的任何内容。
那么,您必须遵循以下步骤:
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 将被转换为大写(就在 case 它将作为小写传递)但如果它为 null 那么它将 默认为V1。然后更改相对路径以显示特定版本 而不是{版本}。
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 替换当前的 ApiExplorer,以便 调用 Configuration.Services.GetApiExplorer() 时返回
现在您可以使用 .../help?version=v1 或 .../help?version=v2 或 .../help?version=v3,您将获得特定的 api 控制器文档。
结果发现和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 将找到您的控制器并获取所有操作。
我最近遇到了类似的问题,并用以下方法解决了我的问题: 2 地点:
public class VersionControllerSelector : IHttpControllerSelector
到
public class VersionControllerSelector : DefaultHttpControllerSelector
...还有...
public VersionControllerSelector(HttpConfiguration config)
到
public VersionControllerSelector(HttpConfiguration config) : base(config)