WebApi HelpPage 上的过滤操作

Filter operations on WebApi HelpPage

我有一个动作调用 "Authenticate" 并且在 WebApiConfig 中我添加了一个映射来调用这个动作。

config.Routes.MapHttpRoute(
        name: "LoginApi",
        routeTemplate: "api/login",
        defaults: new { controller = "Login", action = "Authenticate" }
);

现在在 HelpPage 中我得到了针对同一操作的两个操作,而我只想要一个。

POST api/Login/Authenticate

POST api/Login

如何filter/hide HelpPage 中的操作只显示一个? 喜欢:

POST api/Login

我不能使用[ApiExplorerSettings(IgnoreApi = true)]因为它会隐藏这两个动作

这是我正在使用的包: Microsoft.AspNet.WebApi.HelpPage5.2.7

您不需要任何特殊路线。 DefaultApiroute your action by convention。删除自定义 LoginApi 路由并在控制器中使用约定方法

public class LoginController : ApiController
{
    public void Post()
    {
        // authenticate here
    }
}

或者如果您坚持要命名操作 Authenticate,您可以使用 HTTP 谓词的路由变体

public class LoginController : ApiController
{
    [HttpPost]
    public void Authenticate()
    {
        // authenticate here
    }
}

这将使 API 资源管理器生成您想要的帮助页面:

编辑

要支持共享同一个 HTTP 谓词的多个操作方法,您应该像以前一样按操作名称配置路由,但我在您的路由中没有看到 {action} 参数。应该是:

config.Routes.MapHttpRoute(
    name: "LoginApi",
    routeTemplate: "api/Login/{action}",
    defaults: new { controller = "Login", action = "Authenticate" }
);

通过像上面那样指定默认操作,URL /api/Login 将被正确路由到 LoginController.Authenticate,但是该操作将在帮助页面上显示为 POST api/Login/Authenticate ,因为 ApiExplorer 不知何故无法识别默认操作。要解决这个问题,我宁愿像您在自己的回答中所做的那样远离黑客帮助页面,因为它会反噬您。您可以改为使用 RouteAttribute 为您的默认操作强制路由。然后控制器代码会像这样:

public class LoginController : ApiController
{
    [HttpPost]
    [Route("api/Login")]
    public void Authenticate()
    {
        // authenticate here
    }

    [HttpPost]
    public void Register()
    {
        // register here
    }
}

帮助页面将显示:

POST api/Login

POST api/Login/Register

在文件ApiGroup.cshtml中:

有一个foreach你可以隐藏你想要的操作,像这样:

@foreach (var api in Model)
{
    string[] paths = new string[] { "api/Login/authenticate" };
    if(paths.Contains(api.RelativePath))
    { continue; }

    <tr>
        <td class="api-name">
           <a href="@Url.Action("Api", "Help", 
              new { apiId = api.GetFriendlyId() })">
              @api.HttpMethod.Method @api.RelativePath
           </a></td>
        <td class="api-documentation">
        @if (api.Documentation != null)
        {
            <p>@api.Documentation</p>
        }
        else
        {
            <p>No documentation available.</p>
        }
        </td>
    </tr>
}

在这个块中我添加了这段代码:

string[] paths = new string[] { "api/Login/authenticate" };
if(paths.Contains(api.RelativePath))
{ 
   continue; 
}

有了这个,你可以检查你想展示什么。