Вручную добавьте пользовательский параметр маршрута в документы Swagger с помощью Swashbuckle.AspNetCore - PullRequest
0 голосов
/ 29 августа 2018

Итак, я столкнулся с интересным случаем, когда мне нужно было сгенерировать документацию для REST API, единственной документацией которой был настоящий документ (без встроенной документации XML) и , для которого у меня нет прямого исходного кода доступ. Поэтому я просто написал контроллер-обертку и переопределил каждый маршрут следующим образом:

[HttpGet("this/{that}/the/{other}")]
public override IActionResult GetWhatever(String that, String other) => base.GetWhatever(that, other);

, а затем просто задокументировали его стандартными итоговыми тегами и т. Д. Однако один из переопределенных методов использует внутреннюю строку запроса и не предоставляется в качестве параметра с помощью [FromQuery], поэтому он не может быть автоматически документирован. рефлексивно (и добавление тега для него без фактического параметра не генерирует документацию для него)

Мне нужен способ добавить эту документацию параметров вручную, но каким-либо образом через код (не просто путем добавления его в файл swagger.json). Хотя я мог бы использовать ISchemaFilter от SwaggerGen, чтобы добавить описание параметра к связанному маршруту / методу, но пока мне не повезло.

У кого-нибудь есть пример сделать что-то подобное?

1 Ответ

0 голосов
/ 31 августа 2018

Похоже, что я искал IOpertationFilter . Соединяя это с пользовательским атрибутом, я смог создать то, что мне нужно, чтобы вручную добавить пользовательский параметр в документацию Swagger на лету. См. Весь приведенный ниже код, обратите внимание, Schema / PartialSchema имеет много свойств, я устанавливаю тип только так, как мне нужно, в других случаях может потребоваться больше.

SwaggerParameterAttribute.cs

using System;
using Microsoft.AspNetCore.Mvc.Filters;
using Swashbuckle.AspNetCore.Swagger;

/// <summary>
/// Types of Swagger parameters
/// </summary>
  public enum SwaggerParamType {Body, NonBody};

/// <summary>
/// Attribute to facilitate manually adding a parameter to auto-generated Swagger documentation
/// </summary>
  [AttributeUsage(AttributeTargets.Method, AllowMultiple = true)]
  public class SwaggerParameterAttribute : ActionFilterAttribute {

  /// <summary>
  /// Swagger parameter to inject
  /// </summary>
    public IParameter Parameter { get; set; } 

  /// <summary>
  /// Default constructor
  /// </summary>
  /// <param name="ParamType">Type of Swagger parameter (Body/NonBody)</param>
  /// <param name="Name">Name of the parameter</param>
  /// <param name="Type">Primitive type associated with the parameter (int, bool, string, etc.)</param>
  /// <param name="In">Location of the parameter (path, query, etc.)</param>
  /// <param name="Description">Description of the parameter</param>
  /// <param name="Required">Whether the parameter is required or not (true/false)</param>
    public SwaggerParameterAttribute(SwaggerParamType ParamType, String Name, String Type, String In, String Description = "", Boolean Required = false){
  switch (ParamType) {      
    case SwaggerParamType.Body:
      Parameter = new BodyParameter() { Name = Name, In = In, Description = Description, Required = Required, Schema = new Schema() { Type = Type } };
      break;    
    case SwaggerParamType.NonBody:
      Parameter = new NonBodyParameter() { Name = Name, In = In, Description = Description, Required = Required };  
      ((PartialSchema)Parameter).Type = Type;
      break;
    default:
      throw new ArgumentOutOfRangeException("Invalid Swagger parameter type specified.");
  }
}

SwaggerOperationFilter.cs

using System;
using System.Reflection;
using Microsoft.AspNetCore.Mvc.Controllers;
using Swashbuckle.AspNetCore.Swagger;
using Swashbuckle.AspNetCore.SwaggerGen;

using Whatever.NameSpace.Your.Attribute.Is.In;

/// <summary>
/// Custom Swagger Operation Filter
/// </summary>
  public class SwaggerOperationFilter : IOperationFilter {
    public void Apply(Operation operation, OperationFilterContext context) {
    //Check for [SwaggerParameter] add defined parameter to the parameter list
      foreach (Attribute attribute in ((ControllerActionDescriptor)context.ControllerActionDescriptor).MethodInfo.GetCustomAttributes()) {
        if (attribute.GetType() == typeof(SwaggerParameterAttribute)) {
          operation.Parameters.Add(((SwaggerParameterAttribute)attribute).Parameter);
        }
      }
    }
  }

Startup.cs (только часть фильтра операций чванства)

using Swashbuckle.AspNetCore.Swagger;

using Whatever.NameSpace.Your.Filter.Is.In;

public void ConfigureServices(IServiceCollection services) {
  services.AddSwaggerGen(options => {
    options.OperationFilter<SwaggerOperationFilter>();
  }
}

SomeController.cs (пример использования)

using Swashbuckle.AspNetCore.Swagger;
using Swashbuckle.AspNetCore.SwaggerGen;

using Whatever.NameSpace.Your.Attribute.Is.In;

[HttpGet("this/{that}/the/{other}")]
[SwaggerParameter(ParamType: SwaggerParamType.NonBody, Name: "param1", Type: "string", In: "query", Description: "Some description of param1 here")]
[SwaggerParameter(SwaggerParamType.NonBody, "param2", "string", "query", "Some description of param2 here")]
public override IActionResult GetWhatever(String that, String other) => base.GetWhatever(that, other);
...