[SOLVED] Is there a way to get Swashbuckle to add OData parameters to Web API 2 IQueryable<T> endpoint?

Issue

I have an ASP.Net Web API 2 endpoint that supports OData queries. It is as such:

[HttpGet, Route("")]
public IQueryable<Thing> Get()
{
    return _thingsRepository.Query();
}

The OData $filter parameter and such work great. I just wish they would show up in Swagger like they do for actual OData controllers.

I am using Swashbuckle.OData … but I’m really not sure that it’s buying me anything in this case.

Solution

It turns out it’s pretty easy to add whatever parameters you want to Swagger using SwashBuckle using an IOperationFilter. You can add it in your Swagger Configuration using c.OperationFilter<ODataParametersSwaggerDefinition>();. I created one that adds some OData Parameters to all IQueryable endpoints in my API:

/// <summary>
///     Add the supported odata parameters for IQueryable endpoints.
/// </summary>
public class ODataParametersSwaggerDefinition : IOperationFilter
{
    private static readonly Type QueryableType = typeof(IQueryable);

    /// <summary>
    ///     Apply the filter to the operation.
    /// </summary>
    /// <param name="operation">The API operation to check.</param>
    /// <param name="schemaRegistry">The swagger schema registry.</param>
    /// <param name="apiDescription">The description of the api method.</param>
    public void Apply(Operation operation, SchemaRegistry schemaRegistry, ApiDescription apiDescription)
    {
        var responseType = apiDescription.ResponseType();

        if (responseType.GetInterfaces().Any(i => i == QueryableType))
        {
            operation.parameters.Add(new Parameter
            {
                name = "$filter",
                description = "Filter the results using OData syntax.",
                required = false,
                type = "string",
                @in = "query"
            });

            operation.parameters.Add(new Parameter
            {
                name = "$orderby",
                description = "Order the results using OData syntax.",
                required = false,
                type = "string",
                @in = "query"
            });

            operation.parameters.Add(new Parameter
            {
                name = "$skip",
                description = "The number of results to skip.",
                required = false,
                type = "integer",
                @in = "query"
            });

            operation.parameters.Add(new Parameter
            {
                name = "$top",
                description = "The number of results to return.",
                required = false,
                type = "integer",
                @in = "query"
            });

            operation.parameters.Add(new Parameter
            {
                name = "$count",
                description = "Return the total count.",
                required = false,
                type = "boolean",
                @in = "query"
            });
        }
    }
}

Answered By – Jereme

Answer Checked By – Candace Johnson (BugsFixing Volunteer)

Leave a Reply

Your email address will not be published. Required fields are marked *