ASP.NET Core 3.1 Web API(版本控制)和 Swagger UI 因发布到 Azure 的 MvcJsonOptions 而失败

Ame*_*eya 6 azure swagger-ui asp.net-core-mvc asp.net-core asp.net-core-3.0

我最近将 ASP.NET Core 2.2 Web API 项目迁移到 ASP.NET Core 3.1 Preview 3。我使用基于 URL 的 API 版本控制和 Swagger UI 3.0 (Swashbuckle.AspNetCore 5.0.0-rc4)。一旦 Web API 在 Azure 上发布,我就会收到以下错误(我不确定 Swagger UI 是否与它有关,但是......)

System.InvalidOperationException:无法比较数组中的两个元素。---> System.TypeLoadException:无法从程序集“Microsoft.AspNetCore.Mvc.Formatters.Json”加载类型“Microsoft.AspNetCore.Mvc.MvcJsonOptions”,

参考 Git Hub 中的类似问题,我的理解是该问题已通过预览版 3 解决,并且确实在安装 SDK 3.1.100-preview3 后,我在本地开发机器上看不到此问题。

本地开发机器(一切正常...)

在此处输入图片说明

发布到 Azure Web 服务

由于该框架尚不受支持,因此我将其发布为自包含 Web api 应用程序。发布成功,但我在运行时遇到以下问题...如何解决此问题?

在此处输入图片说明

System.InvalidOperationException: Failed to compare two elements in the array.
 ---> System.TypeLoadException: Could not load type 'Microsoft.AspNetCore.Mvc.MvcJsonOptions' from assembly 'Microsoft.AspNetCore.Mvc.Formatters.Json, Version=3.1.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60'.
   at System.Signature.GetSignature(Void* pCorSig, Int32 cCorSig, RuntimeFieldHandleInternal fieldHandle, IRuntimeMethodInfo methodHandle, RuntimeType declaringType)
   at System.Reflection.RuntimeConstructorInfo.get_Signature()
   at System.Reflection.RuntimeConstructorInfo.GetParametersNoCopy()
   at System.Reflection.RuntimeConstructorInfo.GetParameters()
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteFactory.<>c.<CreateConstructorCallSite>b__16_1(ConstructorInfo a, ConstructorInfo b)
   at System.Collections.Generic.ArraySortHelper`1.SwapIfGreater(T[] keys, Comparison`1 comparer, Int32 a, Int32 b)
   at System.Collections.Generic.ArraySortHelper`1.IntroSort(T[] keys, Int32 lo, Int32 hi, Int32 depthLimit, Comparison`1 comparer)
   at System.Collections.Generic.ArraySortHelper`1.IntrospectiveSort(T[] keys, Int32 left, Int32 length, Comparison`1 comparer)
   at System.Collections.Generic.ArraySortHelper`1.Sort(T[] keys, Int32 index, Int32 length, Comparison`1 comparer)
   --- End of inner exception stack trace ---
   at System.Collections.Generic.ArraySortHelper`1.Sort(T[] keys, Int32 index, Int32 length, Comparison`1 comparer)
   at System.Array.Sort[T](T[] array, Comparison`1 comparison)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteFactory.CreateConstructorCallSite(ResultCache lifetime, Type serviceType, Type implementationType, CallSiteChain callSiteChain)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteFactory.TryCreateExact(ServiceDescriptor descriptor, Type serviceType, CallSiteChain callSiteChain, Int32 slot)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteFactory.TryCreateExact(Type serviceType, CallSiteChain callSiteChain)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteFactory.CreateCallSite(Type serviceType, CallSiteChain callSiteChain)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteFactory.<>c__DisplayClass7_0.<GetCallSite>b__0(Type type)
   at System.Collections.Concurrent.ConcurrentDictionary`2.GetOrAdd(TKey key, Func`2 valueFactory)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteFactory.GetCallSite(Type serviceType, CallSiteChain callSiteChain)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteFactory.CreateArgumentCallSites(Type serviceType, Type implementationType, CallSiteChain callSiteChain, ParameterInfo[] parameters, Boolean throwIfCallSiteNotFound)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteFactory.CreateConstructorCallSite(ResultCache lifetime, Type serviceType, Type implementationType, CallSiteChain callSiteChain)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteFactory.TryCreateExact(ServiceDescriptor descriptor, Type serviceType, CallSiteChain callSiteChain, Int32 slot)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteFactory.TryCreateExact(Type serviceType, CallSiteChain callSiteChain)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteFactory.CreateCallSite(Type serviceType, CallSiteChain callSiteChain)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteFactory.<>c__DisplayClass7_0.<GetCallSite>b__0(Type type)
   at System.Collections.Concurrent.ConcurrentDictionary`2.GetOrAdd(TKey key, Func`2 valueFactory)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteFactory.GetCallSite(Type serviceType, CallSiteChain callSiteChain)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteFactory.CreateArgumentCallSites(Type serviceType, Type implementationType, CallSiteChain callSiteChain, ParameterInfo[] parameters, Boolean throwIfCallSiteNotFound)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteFactory.CreateConstructorCallSite(ResultCache lifetime, Type serviceType, Type implementationType, CallSiteChain callSiteChain)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteFactory.TryCreateExact(ServiceDescriptor descriptor, Type serviceType, CallSiteChain callSiteChain, Int32 slot)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteFactory.TryCreateExact(Type serviceType, CallSiteChain callSiteChain)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteFactory.CreateCallSite(Type serviceType, CallSiteChain callSiteChain)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteFactory.<>c__DisplayClass7_0.<GetCallSite>b__0(Type type)
   at System.Collections.Concurrent.ConcurrentDictionary`2.GetOrAdd(TKey key, Func`2 valueFactory)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteFactory.GetCallSite(Type serviceType, CallSiteChain callSiteChain)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.ServiceProviderEngine.CreateServiceAccessor(Type serviceType)
   at System.Collections.Concurrent.ConcurrentDictionary`2.GetOrAdd(TKey key, Func`2 valueFactory)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.ServiceProviderEngine.GetService(Type serviceType, ServiceProviderEngineScope serviceProviderEngineScope)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.ServiceProviderEngineScope.GetService(Type serviceType)
   at Microsoft.AspNetCore.Builder.UseMiddlewareExtensions.GetService(IServiceProvider sp, Type type, Type middleware)
   at lambda_method(Closure , Object , HttpContext , IServiceProvider )
   at Microsoft.AspNetCore.Builder.UseMiddlewareExtensions.<>c__DisplayClass4_1.<UseMiddleware>b__2(HttpContext context)
Run Code Online (Sandbox Code Playgroud)

Jim*_*Aho 5

对于 ASP.NET Core 3.0(和 3.1),请确保Swashbuckle.AspNetCore至少面向版本 5.0(不是 RC 版本)。这应该可以解决该特定问题。

您遇到此问题的原因是 Swagger 以前依赖于MvcJsonOptionsASP.NET Core 框架的一部分。Swagger 加载并尝试查找该类,但它不存在。但现在由于 ASP.NET Core 框架使用 System.Text.Json 而不是 Newtonsoft.Json 导致编译错误。

关于同一主题,我建议您阅读此处,其中解释了如果您仍想继续使用 Newtonsoft.Json,如何选择加入。

一般来说,Swagger 的实现发生了一些重大变化。这里有关于4.0 中的中断5.0 中的中断的很好的文档。