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

jms*_*msb 4 routing asp.net-web-api attributerouting asp.net-web-api-helppages

我目前正在使用Web API 2的属性路由实现Web API(http://www.asp.net/web-api/overview/web-api-routing-and-actions/attribute-routing-in-web-api -2).我还使用"帮助页面"模块,以便从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.
}
Run Code Online (Sandbox Code Playgroud)

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

www.example.com/api/Controller/Path/Foo 
www.example.com/api/Controller/Path/Foo.json
www.example.com/api/Controller/Path/Foo.xml
Run Code Online (Sandbox Code Playgroud)

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

api/Controller/Foo
api/Controller/Foo.{ext}
Run Code Online (Sandbox Code Playgroud)

但我只想看到:

api/Controller/Foo.{ext}
Run Code Online (Sandbox Code Playgroud)

我宁愿在每个方法上隐藏非扩展路由,这样每个方法只显示一个帮助页面条目.

有没有其他人尝试类似的东西?有没有我失踪的工作?

Kir*_*lla 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
    }
    
    Run Code Online (Sandbox Code Playgroud)
  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);
        }
    }
    
    Run Code Online (Sandbox Code Playgroud)
  3. ApiDescription从默认值中获取所有列表,ApiExplorer然后过滤掉您不喜欢的描述.例: Configuration.Services.GetApiExplorer().ApiDescriptions.Where((apiDesc) => !apiDesc.RelativePath.EndsWith("Path/Foo", StringComparison.OrdinalIgnoreCase))