在Web API 2中使用属性路由时限制自动帮助页面内容

时间:2013-10-25 13:57:46

标签: asp.net-web-api routing attributerouting asp.net-web-api-helppages

我目前正在使用Web API 2的属性路由(http://www.asp.net/web-api/overview/web-api-routing-and-actions/attribute-routing-in-web-api-2)实现Web API。我还使用“帮助页面”模块,以便从XML注释(http://www.asp.net/web-api/overview/creating-web-apis/creating-api-help-pages)自动生成文档。

对于这个API,我提供了对可选返回格式扩展的支持,因此每个API方法都有一对定义的路由,如下所示:

[HttpGet]
[Route("Path/Foo")]
[Route("Path/Foo.{ext}")]
public HttpResponseMessage DoFoo()
{
    // Some API function.
}

这允许用户点击其中任何一个并获得结果:

www.example.com/api/Controller/Path/Foo 
www.example.com/api/Controller/Path/Foo.json
www.example.com/api/Controller/Path/Foo.xml

我的问题是,当帮助页面使用MapHttpAttributeRoutes()生成文档时,它会为每个方法选择两个路径。所以现在我看到了帮助:

api/Controller/Foo
api/Controller/Foo.{ext}

但我想只看到:

api/Controller/Foo.{ext}

我更希望在每个方法上隐藏非扩展路由,以便每个方法只显示一个帮助页面条目。

还有其他人尝试过类似的东西吗?是否有我失踪的工作?

1 个答案:

答案 0 :(得分:9)

我的问题是,你的api的消费者会很容易理解{ext}是可选的吗?...个人而言,我更喜欢默认行为......但无论如何以下是我的一些解决方法可以想到:

  1. 快速而肮脏的解决方法。将DoFoo拆分为2个动作,如DoFoo()和DoFooWithExt。请注意,我使用的是名为ApiExplorerSettings的属性,用于HelpPage目的。示例如下:

    [HttpGet]
    [Route("Path/Foo")]
    [ApiExplorerSettings(IgnoreApi=true)]
    public HttpResponseMessage DoFoo()
    {
        return DoFooHelper();
    }
    
    [HttpGet]
    [Route("Path/Foo.{ext}")]
    public HttpResponseMessage DoFooWithExt()
    {
        return DoFooHelper();
    }
    
    private HttpResponseMessage DoFooHelper()
    {
        //do something
    }
    
  2. 创建自定义ApiExplorer(内部使用HelpPage功能)并检查以下特定路线,并决定是否显示该特定路线的操作。

    // update the config with this custom implementation
    config.Services.Replace(typeof(IApiExplorer), new CustomApiExplorer(config));
    
    public class CustomApiExplorer : ApiExplorer
    {
        public CustomApiExplorer(HttpConfiguration config) : base(config)
        {
    
        }
    
        public override bool ShouldExploreAction(string actionVariableValue, HttpActionDescriptor actionDescriptor, IHttpRoute route)
        {
            if (route.RouteTemplate.EndsWith("Path/Foo", StringComparison.OrdinalIgnoreCase))
            {
                return false;
            }
    
            return base.ShouldExploreAction(actionVariableValue, actionDescriptor, route);
        }
    }
    
  3. 从默认ApiDescription获取所有ApiExplorer的列表,然后过滤掉您不喜欢的说明。例: Configuration.Services.GetApiExplorer().ApiDescriptions.Where((apiDesc) => !apiDesc.RelativePath.EndsWith("Path/Foo", StringComparison.OrdinalIgnoreCase))