使用基于命名空间的ApiControllers定制ApiExplorer

时间:2014-02-10 23:41:40

标签: asp.net-mvc api documentation asp.net-apicontroller asp.net-mvc-apiexplorer

我正在尝试在后端系统中添加API文档。 默认ApiExplorer和帮助页面工作非常好,直到我向Api控制器介绍版本。

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

  • v1
  • V2
  • V3

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

这破坏了我的默认ApiExplorer,以下属性返回ZERO api说明

Configuration.Services.GetApiExplorer().ApiDescriptions

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

请告知。

3 个答案:

答案 0 :(得分:7)

我会告诉你一种方法。此代码仅供学习。在这里,我不是在谈论设计和最佳实践,所以随时随地改变你想要的东西。

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

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将转换为upperCase(仅在   case它将作为lowerCase传递但是如果它是null则它会   以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控制器文档。

答案 1 :(得分: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将找到您的控制器并获取所有操作。

答案 2 :(得分:1)

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

public class VersionControllerSelector : IHttpControllerSelector

public class VersionControllerSelector : DefaultHttpControllerSelector

...和...

public VersionControllerSelector(HttpConfiguration config)

public VersionControllerSelector(HttpConfiguration config) : base(config)