Listing API Methods Under Multiple Groups

扶醉桌前 提交于 2020-01-01 18:17:21

问题


I have Swashbuckle annotated code that looks like this:

[Route("api/Subscribers/{id}/[controller]")]
[Route("api/Organizations/{id}/[controller]")]
public class AddressesController : Controller
{
    [HttpGet("{aid}")]
    [SwaggerResponse(HttpStatusCode.OK, Type = typeof(PostalRecord))]
    public async Task<IActionResult> GetAddress(Guid id, Guid aid)
    {
       //do something
    }

I would like to use the GroupActionsBy customization, as shown in this example, but I want to have the above GetAddress method simultaneously included into two separate groups that correspond to the two route prefixes shown:

[Route("api/Subscribers/{id}/[controller]")]
[Route("api/Organizations/{id}/[controller]")]

In other words, I want the same method to be listed under both:

  • Subscribers
  • Organizations

How can this be done?

Incidentally, I'm working with ASP.NET Core (dnx46). If it is not yet possible to do this with the ASP.NET Core version of Swashbucklee, then a full-CLR (Web API 2.2?) example would still be appreciated.

Also, for a more complete story of what I'm trying to do - I have a separate SO post.

Update

The answer given by @venerik got me close to the solution. When I apply his sample code...

[SwaggerOperation(Tags = new []{"Subscribers", "Organizations"})]

...this causes the Swagger listings to look like this:

In short, the "Addresses" endpoints are now appearing under the headings that I want but, as the red arrow indicates, they are now also being "cross-listed"; I don't want the "Subscribers" endpoint being listed under the "Organizations" endpoint.

I'm suspicious that a [SwaggerOperationFilter] might be "the other half" of the answer, if I can make it remove the cross-listed entries. I've not played with that mechanism before.

Angst

Also, it is very unfortunate that [SwaggerOperation] can only be applied on methods/actions. I would rather apply it to the class itself:

[Route("api/Subscribers/{id}/[controller]")]
[Route("api/Organizations/{id}/[controller]")]
[SwaggerOperation(Tags = new []{"Subscribers", "Organizations"})]
public class AddressesController : Controller
{

Is there any remedy for this?


回答1:


@venerik got me on the right path. But instead of a [SwaggerOperation] attribute, what I needed was a [SwaggerOperationFilter], like this:

public class CategorizeFilter : IOperationFilter
{
    public void Apply(Operation operation, OperationFilterContext context)
    {
        string path = context.ApiDescription.RelativePath;
        string segment = path.Split('/')[1];

        if (segment != context.ApiDescription.GroupName)
        {
            operation.Tags = new List<string> { segment };
        }
    }
}

Then I just decorate my actions as needed:

[Route("api/Subscribers/{id}/[controller]")]
[Route("api/Organizations/{id}/[controller]")]
public class AddressesController : Controller
{
    [HttpGet("{aid}")]
    [SwaggerOperationFilter(typeof(CategorizeFilter))]
    [SwaggerResponse(HttpStatusCode.OK, Type = typeof(PostalRecord))]
    public async Task<IActionResult> GetAddress(Guid id, Guid aid)
    {
       //do something
    }

As a consequence, the "Addresses" category completely disappeared from my Swagger UI (good!) and the twin set of endpoint routes are properly divided between "Organizations" and "Subscribers" groups. Perfect!




回答2:


I do not have experience with ASP.NET Core (yet) but in ASP.NET Web API you can achieve this with the SwaggerOperationAttribute. You can use this attribute to add tags to operations. For instance, the next piece of code adds the tags Subscribers and Organizations:

[SwaggerOperation(Tags = new []{"Subscribers", "Organizations"})]
public async Task<IActionResult> GetAddress(Guid id, Guid aid)
{
   //do something
}

Swagger-UI groups operations by tag, so, GetAddress will get listed under both Subscribers and Organizations.



来源:https://stackoverflow.com/questions/36523866/listing-api-methods-under-multiple-groups

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!