Skip to content

Instantly share code, notes, and snippets.

@ArwynFr
Last active October 9, 2023 11:40
Show Gist options
  • Select an option

  • Save ArwynFr/18db8f77055b79d6e44cd2426ada49c0 to your computer and use it in GitHub Desktop.

Select an option

Save ArwynFr/18db8f77055b79d6e44cd2426ada49c0 to your computer and use it in GitHub Desktop.
OpenApi ASP.NET Core OData 8

ASP.NET Core OData 8

This Gist contains code which allows ApiExplorer + ApiVersioning + OData 8 + Swashbuckle to work together

It was tested with the following libraries:

  • Asp.Vesioning.OData.ApiExplorer 7.0.2

  • Swashbuckle.AspNetCore 6.5.0

  • Microsoft.AspNetCore.OData 8.0.12

In order to work, you MUST:

  • use conventional routing on your controller: no RouteAttribute, no HttpGetAtribute, …​

  • use conventional controllers versinoning: name your controller [Controller][Version]Controller

  • decorate controllers with ApiVersionAttribute

  • use a separate controller for each version

using Asp.Versioning.ApiExplorer;
using Microsoft.Extensions.Options;
using Microsoft.OpenApi.Models;
using Swashbuckle.AspNetCore.SwaggerGen;
public class ConfigureSwaggerOptions : IConfigureOptions<SwaggerGenOptions>
{
private readonly IApiVersionDescriptionProvider provider;
public ConfigureSwaggerOptions(IApiVersionDescriptionProvider provider) => this.provider = provider;
public void Configure(SwaggerGenOptions options)
{
foreach (var description in provider.ApiVersionDescriptions)
{
options.SwaggerDoc(
description.GroupName,
new OpenApiInfo()
{
Title = "API title",
Description = "API description",
Version = description.ApiVersion.ToString(),
});
}
}
}
using Microsoft.AspNetCore.OData;
using Microsoft.Extensions.Options;
using Swashbuckle.AspNetCore.SwaggerGen;
internal static class OpenApiExtensions
{
public static IServiceCollection AddOpenApiServices(this IServiceCollection services)
{
services.AddControllers().AddOData(options =>
{
options.RouteOptions.EnableKeyInParenthesis = false;
});
services.AddApiVersioning(options =>
{
options.ReportApiVersions = true;
options.AssumeDefaultVersionWhenUnspecified = true;
}).AddOData(options =>
{
// you can add api/ or odata/ prefix here if you want
options.AddRouteComponents("v{version:apiVersion}");
}).AddODataApiExplorer(options =>
{
options.GroupNameFormat = "'v'VVV";
options.SubstituteApiVersionInUrl = true;
options.AssumeDefaultVersionWhenUnspecified = true;
});
return services
.AddSwaggerGen()
.AddTransient<IConfigureOptions<SwaggerGenOptions>, ConfigureSwaggerOptions>();
}
public static WebApplication UseOpenApi(this WebApplication app) => app
.UseSwagger()
.UseSwaggerUI(options =>
{
foreach (var description in app.DescribeApiVersions().Select(description => description.GroupName))
{
options.SwaggerEndpoint($"/swagger/{description}/swagger.json", description);
}
});
}
using Asp.Versioning;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.OData.Query;
using Microsoft.AspNetCore.OData.Routing.Controllers;
[ApiVersion("1.0")]
public class Users1Controller : ODataController
{
// GET ~/v1/Users
[EnableQuery]
[ProducesResponseType(typeof(User), StatusCodes.Status200OK)]
public IActionResult Get() => Ok(new[] { new { Id = 1, Name = "Arwyn" } });
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment