From 09be3b3f60a5e28dbc556ce47eac37165d716389 Mon Sep 17 00:00:00 2001
From: Bart Koelman <10324372+bkoelman@users.noreply.github.com>
Date: Tue, 21 Oct 2025 01:27:05 +0200
Subject: [PATCH] Throw at startup when different OpenAPI version is loaded
---
.../ServiceCollectionExtensions.cs | 38 +++++++++++++++----
1 file changed, 31 insertions(+), 7 deletions(-)
diff --git a/src/JsonApiDotNetCore/Configuration/ServiceCollectionExtensions.cs b/src/JsonApiDotNetCore/Configuration/ServiceCollectionExtensions.cs
index 65bf465ce3..f82fcd3f23 100644
--- a/src/JsonApiDotNetCore/Configuration/ServiceCollectionExtensions.cs
+++ b/src/JsonApiDotNetCore/Configuration/ServiceCollectionExtensions.cs
@@ -1,3 +1,4 @@
+using System.Reflection;
using JetBrains.Annotations;
using JsonApiDotNetCore.Errors;
using JsonApiDotNetCore.Repositories;
@@ -13,6 +14,16 @@ public static class ServiceCollectionExtensions
{
private static readonly TypeLocator TypeLocator = new();
+ ///
+ /// Configures JsonApiDotNetCore by registering resources from an Entity Framework Core model.
+ ///
+ public static IServiceCollection AddJsonApi(this IServiceCollection services, Action? options = null,
+ Action? discovery = null, Action? resources = null, IMvcCoreBuilder? mvcBuilder = null)
+ where TDbContext : DbContext
+ {
+ return AddJsonApi(services, options, discovery, resources, mvcBuilder, [typeof(TDbContext)]);
+ }
+
///
/// Configures JsonApiDotNetCore by registering resources manually.
///
@@ -23,20 +34,33 @@ public static IServiceCollection AddJsonApi(this IServiceCollection services, Ac
#pragma warning restore AV1553 // Do not use optional parameters with default value null for strings, collections or tasks
{
ArgumentNullException.ThrowIfNull(services);
+ AssertCompatibleOpenApiVersion();
SetupApplicationBuilder(services, options, discovery, resources, mvcBuilder, dbContextTypes ?? Array.Empty());
return services;
}
- ///
- /// Configures JsonApiDotNetCore by registering resources from an Entity Framework Core model.
- ///
- public static IServiceCollection AddJsonApi(this IServiceCollection services, Action? options = null,
- Action? discovery = null, Action? resources = null, IMvcCoreBuilder? mvcBuilder = null)
- where TDbContext : DbContext
+ private static void AssertCompatibleOpenApiVersion()
{
- return AddJsonApi(services, options, discovery, resources, mvcBuilder, [typeof(TDbContext)]);
+ Version thisAssemblyVersion = typeof(IJsonApiOptions).Assembly.GetName().Version!;
+ Version? openApiAssemblyVersion = TryGetOpenApiAssemblyVersion();
+
+ if (openApiAssemblyVersion != null && openApiAssemblyVersion != thisAssemblyVersion)
+ {
+ throw new InvalidOperationException(
+ $"JsonApiDotNetCore v{thisAssemblyVersion.ToString(3)} is incompatible with JsonApiDotNetCore.OpenApi.Swashbuckle v{openApiAssemblyVersion.ToString(3)}. " +
+ $"Reference a matching (preview) version of the JsonApiDotNetCore.OpenApi.Swashbuckle NuGet package.");
+ }
+ }
+
+ private static Version? TryGetOpenApiAssemblyVersion()
+ {
+ Assembly? openApiAssembly = AppDomain.CurrentDomain.GetAssemblies().FirstOrDefault(assembly =>
+ assembly.FullName?.StartsWith("JsonApiDotNetCore.OpenApi.Swashbuckle", StringComparison.Ordinal) == true &&
+ assembly.GetName().Name == "JsonApiDotNetCore.OpenApi.Swashbuckle");
+
+ return openApiAssembly?.GetType("JsonApiDotNetCore.OpenApi.Swashbuckle.ServiceCollectionExtensions", false)?.Assembly.GetName().Version;
}
private static void SetupApplicationBuilder(IServiceCollection services, Action? configureOptions,