web-dev-qa-db-fra.com

Swashbuckle défini manuellement operationId, plusieurs opérations avec le même verbe

J'ai besoin de savoir s'il est possible de configurer un identifiant d'opération personnalisé ou une convention de dénomination, je veux dire que je sais que le filtre d'opération peut être écrasé de la manière dont est généré operationId

https://Azure.Microsoft.com/en-us/documentation/articles/app-service-api-dotnet-swashbuckle-customize/

using Swashbuckle.Swagger;
using System.Web.Http.Description;

namespace Something
{
    public class MultipleOperationsWithSameVerbFilter : IOperationFilter
    {
        public void Apply(
            Operation operation,
            SchemaRegistry schemaRegistry,
            ApiDescription apiDescription)
        {
            if (operation.parameters != null)
            {
                operation.operationId += "By";
                foreach (var parm in operation.parameters)
                {
                    operation.operationId += string.Format("{0}",parm.name);
                }
            }
        }
    }
}

dans SwaggerConfig.cs

 c.OperationFilter<MultipleOperationsWithSameVerbFilter>();

Maintenant, cela est utile pour transformer la description du fanfaron, vérifiez ci-dessous:

enter image description here

Très bien, maintenant je me retrouve avec un autre problème, exemple similaire avec peut cas: sur le même contrôleur, j'ai deux points de terminaison

  • Poste:/client corporel: {email, lieu ....}
  • Message:/client/recherche corporelle: {un filtre, peu importe}

L'exemple n'est pas tout à fait correct (le dernier message devrait être un get), mais toujours en supposant que webapi ne peut pas être changé (nouveau contrôleur pour la séparation) pour ce cas particulier, j'essaierai de trouver un moyen de générer operationId différent pour chaque action, mais ma question est la suivante:

Est-il possible de décorer en quelque sorte les actions du contrôleur similaires à [JsonIgnore] ou à [Route ("client/supprimer")], pour être explicite sur le operationId .

16
SilentTremor

[~ # ~] modifier [~ # ~] Cette réponse concerne Swashbuckle 5.6 et .NET Framework. Veuillez lire réponse de mwilson pour Swashbuckle et .NET Core

Vous pouvez utiliser le SwaggerOperationAttribute fourni par Swashbuckle pour cela.

[SwaggerOperation("get")]
public IEnumerable<Contact> Get()
{
    ....
}

[SwaggerOperation("getById")]
public IEnumerable<Contact> Get(string id)
{
    ...
}

Vous pouvez également utiliser cet attribut pour ajouter des balises et des schémas à votre opération. Jetez un œil au code source

25
venerik

Pour swashbuckle 5.0, vous pouvez utiliser l'attribut Name

[HttpGet("{id}", Name = "GetProductById")]
public IActionResult Get(int id) // operationId = "GetProductById"'

Il y a quelques autres options listées ici

5
mwilson

PDATE: pour avoir une importation fonctionnelle d'API de repos dans Visual Studio sans beaucoup de refactoring (ajout à la main du nom de l'opération)

J'ai un peu mis à jour le filtre d'opération personnalisé, celui-ci génère des identifiants uniques dans 99% des cas. Le pourcentage restant provenait d'une mise en œuvre malheureuse de l'API.

  public class MultipleOperationsWithSameVerbFilter : IOperationFilter
    {
        public void Apply(
            Operation operation,
            SchemaRegistry schemaRegistry,
            ApiDescription apiDescription)
        {
            string refsSwaggerIds = string.Empty;
            operation.parameters?.ForEach(x =>
            {
                if (!string.IsNullOrEmpty(x.schema?.@ref) &&
                    !string.IsNullOrEmpty([email protected]('/').LastOrDefault()))
                {
                    refsSwaggerIds += [email protected]('/').LastOrDefault();
                }
                else
                {
                    refsSwaggerIds += x.name;
                }
            });
            operation.operationId += !string.IsNullOrEmpty(refsSwaggerIds)
                ? refsSwaggerIds
                : apiDescription.RelativePath?.Replace("/", "_").Replace("{", "").Replace("}", "");
        }
    }


 public class HandleComplexTypesFromUri : IOperationFilter
    {
        public void Apply(Operation operation, SchemaRegistry schemaRegistry, ApiDescription apiDescription)
        {
            //this is incorect form swager helper pov, but for rest api import in visual studio is the only way for GET with complex type to be imported
            if (operation.parameters == null || apiDescription.HttpMethod.Method != "GET")
                return;
            var models = schemaRegistry.Definitions;
            var apiParams = apiDescription.ParameterDescriptions;

            if (apiParams.Count == operation.parameters.Count) return;
            foreach (var apiParameterDescription in apiParams)
            {
                if (!models.ContainsKey(apiParameterDescription.ParameterDescriptor.ParameterType.Name))
                    continue;
                operation.parameters =
                    operation.parameters.Where(
                        x =>
                            x.@in != "query" ||
                            (x.@in == "query" && !x.name.StartsWith(apiParameterDescription.Name + "."))).ToList();
                if (operation.parameters.Count(x => x.name == apiParameterDescription.Name) == 0)
                {
                    //var t = Type.GetType(apiParameterDescription.ParameterDescriptor.ParameterType.Name);
                    operation.parameters.Add(new Parameter
                    {
                        name = apiParameterDescription.Name.ToLowerInvariant(),
                        //type = apiParameterDescription.ParameterDescriptor.ParameterType.Name,
                        @in = "query",
                        required = true,
                        schema = schemaRegistry.GetOrRegister(apiParameterDescription.ParameterDescriptor.ParameterType)
                        //schema = models[apiParameterDescription.ParameterDescriptor.ParameterType.Name]
                    });
                }
            }
        }

Dans la configuration swagger, utilisez

GlobalConfiguration.Configuration 
                .EnableSwagger(c =>
                   // at some point
                 c.OperationFilter<HandleComplexTypesFromUri>();
                 c.OperationFilter<MultipleOperationsWithSameVerbFilter>();
})// the rest ...
1
SilentTremor