Asp.Net核心Swashbuckle设置operationId

时间:2018-09-10 17:34:19

标签: asp.net-core swagger swashbuckle

我如何在Asp.Net Core 2.1项目中设置高大的operationId属性?根据{{​​3}}的帖子,我应该使用SwaggerOperationAttribute,但在Swashbuckle.AspNetCore库中找不到它。还有一个IOperationFilter

  public interface IOperationFilter
  {
    void Apply(Operation operation, OperationFilterContext context);
  }

而且我找不到任何用于大张旗鼓生成目的的实现方式。

4 个答案:

答案 0 :(得分:3)

还有2个其他选项,而无需编写任何额外的代码或添加诸如Swashbuckle.AspNetCore.Annotations

之类的额外依赖项

选项1 :基于约定-SwaggerGen可以选择设置CustomOperationIds。因此,您可以像这样简单地将其设置为使用ControllerName_HttpMethod

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

这将遵循ControllerName_HttpMethod约定将operationIds添加到您的所有方法中。

选项2 :基于ActionFilter /属性-您可以配置每个Action方法(就像您通过简单地向您的SwaggerOperation属性添加Name操作过滤器一样HTTP动词操作过滤器是这样的:

[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);
}

这与[SwaggerOperation(OperationId = "Post_Person")]完全一样,但是不需要EnableAnnotations

答案 1 :(得分:2)

Name 参数添加到 [HttpGet]/[HttpPost] 失败并在最新版本中出现异常,但在 Name 属性上放置了 Route 参数似乎工作:

    /// <summary>
    /// Get all devices
    /// </summary>
    [Route("devices", Name = "GetAllDevices")]
    [Authorize]
    [HttpGet]
    [Produces(typeof(Device[]))]
    public async Task<IActionResult> GetAllDevices() { ...}

答案 2 :(得分:1)

您可以使用Swashbuckle.AspNetCore.Annotations nuget包在swagger上启用注释。 (https://github.com/domaindrivendev/Swashbuckle.AspNetCore/blob/master/README.md#swashbuckleaspnetcoreannotations

启用注释后,您可以通过使用SwaggerOperationAttribute装饰动作来丰富生成的Operation元数据。

[HttpPost]

[SwaggerOperation(
    Summary = "Creates a new product",
    Description = "Requires admin privileges",
    OperationId = "CreateProduct",
    Tags = new[] { "Purchase", "Products" }
)]
public IActionResult Create([FromBody]Product product)

答案 3 :(得分:0)

最后,我来到了这个解决方案:

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)
{
    ...
}

但是在我看来,我还是重新发明了轮子。