8

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.

Jonathan L.
  • 682
  • 6
  • 10

2 Answers2

8

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

MindSwipe
  • 7,193
  • 24
  • 47
  • Hello, could you please explain the reasoning behind this approach? Is it only because the [Obsolete] cannot be applied to parameters, or is there a deeper reasoning? Using a custom attribute and swashbuckle filter allows for parameter deprecation in general so I was wondering if there are some issues with doing that. – Zdeněk Jelínek Dec 08 '22 at 12:20
1

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

  • Thanks a lot! This worked out when I replaced simple parameters list at my endpoint with a class like this: public IActionResult FilterTaskList([FromQuery]SearchRequest request) and added ObsoleteAttribute to it's particular properties. – Dudar Jun 29 '23 at 14:53