Jonathan L.
Jonathan L.

Reputation: 682

Mark a WebApi method's parameter as obsolete / deprecated for Swashbuckle / Swagger

As per my understanding of the Swagger Specification, it's possible to mark a parameter as obsolete:

Deprecated Parameters

Use deprecated: true to mark a parameter as deprecated.

        - in: query
          name: format
          required: true
          schema:
            type: string
            enum: [json, xml, yaml]
          deprecated: true
          description: Deprecated, use the appropriate `Accept` header instead.```

How can I have Swashbuckle generate this for a parameter?

Why?

I have a controller method something like the following:

[HttpGet]
public async Task<IActionResult> Execute(bool? someName)
{
}

And I want to change the querystring parameter name while temporarily remaining backwards compatible, so I want to do something like:

[HttpGet]
public async Task<IActionResult> Execute([Obsolete("Use someNewName instead.")] bool? someName, bool? someNewName)
{
    someNewName = someNewName ?? someName;
}

However, Obsolete cannot be applied to a parameter. I expected that Swashbuckle.AspNetCore.Annotations might be a place to find this kind of functionality, but it doesn't seem to have it.

Upvotes: 8

Views: 9514

Answers (2)

Ivan Magnin-oddos
Ivan Magnin-oddos

Reputation: 29

it is possible to go through a OperationFilter

in programe.cs set

options.OperationFilter<OpenApiParameterObsoleteFilter>();

create OpenApiParameterObsoleteFilter.cs file in OpenApiParameterObsoleteFilter set

 public class OpenApiParameterIgnoreFilter : Swashbuckle.AspNetCore.SwaggerGen.IOperationFilter
{
    public void Apply(Microsoft.OpenApi.Models.OpenApiOperation operation, Swashbuckle.AspNetCore.SwaggerGen.OperationFilterContext context)
    {
        if (operation == null || context == null || context.ApiDescription?.ParameterDescriptions == null)
            return;

        var parametersToHide = context.ApiDescription.ParameterDescriptions
            .Where(parameterDescription => ParameterHasIgnoreAttribute(parameterDescription))
            .ToList();


        var parametersToObsolete = context.ApiDescription.ParameterDescriptions
                .Where(parameterDescription => ParameterHasDepreciate(parameterDescription))
                .ToList();
        foreach (var parameterToObsolete in parametersToObsolete)
        {
            var parameter = operation.Parameters.FirstOrDefault(parameter => string.Equals(parameter.Name, parameterToObsolete.Name, System.StringComparison.Ordinal));
            parameter.Deprecated = true;
        }

    }
    private static bool ParameterHasDepreciate(Microsoft.AspNetCore.Mvc.ApiExplorer.ApiParameterDescription parameterDescription)
    {
        if (parameterDescription.ModelMetadata is Microsoft.AspNetCore.Mvc.ModelBinding.Metadata.DefaultModelMetadata metadata)
        {
            return
                (metadata.Attributes.Attributes?.Any(attribute => attribute.GetType() == typeof(ObsoleteAttribute)) ?? false);
        }

        return false;
    }
}

Add Obsolete attribut on your parameter(in an object in my case)

    [Obsolete]
    public long? ID_CONDUCT { get => iD_CONDUCT; set => iD_CONDUCT = value; }

In swagger you have this result result

Upvotes: 1

MindSwipe
MindSwipe

Reputation: 7940

You don't mark a parameter as obsolete, if a parameter becomes obsolete, the whole method becomes obsolete. You'll need to declare a new method, with a new method signature, and mark the old method as obsolete. Like so

[HttpGet]
[Obsolete("Use Execute with bool? someNewName instead.")]
public async Task<IActionResult> Execute(bool? someName)
{
}

[HttpGet]
public async Task<IActionResult> Execute(bool? someNewName)
{
}

If you only changed the name of the parameter, you can instead use the Bind attribute to bind a URI element to a differently named variable, like so:

[HttpGet]
public async Task<IActionResult> Execute([Bind(Prefix = "someNewName")] bool? someName)
{
}

This would allow you to continue to use the same method, without having to forcibly change all your clients. But, if more than just the name of the parameter changed, for example the type, you'll need a new method

Upvotes: 8

Related Questions