Search code examples
asp.netasp.net-web-api2odataswashbuckle

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


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"
                });
            }
        }
    }