Asp.Net core Swashbuckle set operationId

前端 未结 3 1947
梦谈多话
梦谈多话 2021-01-02 15:59

How can I set swagger operationId attribute in Asp.Net Core 2.1 project? According to this post I should use SwaggerOperationAttribute but I cannot

相关标签:
3条回答
  • 2021-01-02 16:41

    You can enable annotation on swagger with the Swashbuckle.AspNetCore.Annotations nuget package. (https://github.com/domaindrivendev/Swashbuckle.AspNetCore/blob/master/README.md#swashbuckleaspnetcoreannotations)

    Once annotations have been enabled, you can enrich the generated Operation metadata by decorating actions with a SwaggerOperationAttribute.

    [HttpPost]
    
    [SwaggerOperation(
        Summary = "Creates a new product",
        Description = "Requires admin privileges",
        OperationId = "CreateProduct",
        Tags = new[] { "Purchase", "Products" }
    )]
    public IActionResult Create([FromBody]Product product)
    
    0 讨论(0)
  • 2021-01-02 16:48

    There are 2 other options without having to write any extra code or add extra dependency like Swashbuckle.AspNetCore.Annotations

    Option 1: Convention based - SwaggerGen has an option to set CustomOperationIds. So you can simply set it to use ControllerName_HttpMethod like this:

    services.AddSwaggerGen(c =>
    {
        c.CustomOperationIds(e => $"{e.ActionDescriptor.RouteValues["controller"]}_{e.HttpMethod}");
        c.SwaggerDoc("v1", new Info { Title = "Test API", Version = "v1" });
    });
    

    This will add operationIds to all your methods, following ControllerName_HttpMethod convention.

    Option 2: ActionFilter/Attribute based - you can configure each Action method (as you'd do with SwaggerOperation action filter by simple adding a Name property to your HTTP verb action filter like this:

    [HttpPost(Name="Post_Person")]
    [ProducesResponseType(200)]
    [ProducesResponseType(400)]
    [ProducesResponseType(500)]
    public async Task<ActionResult<Response>> PostAsync([FromBody]Request request)
    {
        Response result = await _context.PostAsync(request);
        return Ok(result);
    }
    

    This works exactly like [SwaggerOperation(OperationId = "Post_Person")] but without the need of EnableAnnotations

    0 讨论(0)
  • 2021-01-02 16:54

    Finally, I came to this solution:

    public class SwaggerOperationNameFilter : IOperationFilter
    {
        public void Apply(Operation operation, OperationFilterContext context)
        {
            operation.OperationId = context.MethodInfo.DeclaringType.GetCustomAttributes(true)
                .Union(context.MethodInfo.GetCustomAttributes(true))
                .OfType<SwaggerOperationAttribute>()
                .Select(a => a.OperationId)
                .FirstOrDefault();
        }
    }
    
    [AttributeUsage(AttributeTargets.Method)]
    public sealed class SwaggerOperationAttribute : Attribute
    {
        public SwaggerOperationAttribute(string operationId)
        {
            OperationId = operationId;
        }
    
        public string OperationId { get; }
    }
    
    // Startup.cs
    services.AddSwaggerGen(c =>
    {
        ...
        c.OperationFilter<SwaggerOperationNameFilter>();
    };
    
    [HttpGet("{id:int}")]
    [SwaggerOperation("GetById")]
    public async Task<IActionResult> Get(int id)
    {
        ...
    }
    

    But it still seems to me that I've reinvented the wheel.

    0 讨论(0)
提交回复
热议问题