背景

我用了一个叫Unchase.Swashbuckle.AspNetCore.Extensions的库来加强Swagger的文档,我一般写法是这样的:

builder.Services.AddSwaggerGen(c =>
{
//文档
c.SwaggerDoc("v1", new OpenApiInfo
{
Title = "『xxx』后端接口:myapi",
Version = "v1"
});
c.SwaggerDoc("v2", new OpenApiInfo { Title = "v2", Version = "v2" });
c.MapType<long>(() => new OpenApiSchema { Type = "string" }); //获取注释
var apiXmlPath = Path.Combine(AppContext.BaseDirectory, $"{Assembly.GetExecutingAssembly().GetName().Name}.xml");
c.IncludeXmlComments(apiXmlPath); c.DescribeAllParametersInCamelCase();
c.AddEnumsWithValuesFixFilters(services, o =>
{
o.IncludeDescriptions = true;
o.IncludeXEnumRemarks = true;
o.DescriptionSource = DescriptionSources.DescriptionAttributesThenXmlComments;
o.IncludeXmlCommentsFrom(apiXmlPath);
});
}); ... var app = builder.Build(); // Configure the HTTP request pipeline.
if (app.Environment.IsDevelopment())
{
app.UseSwagger();
app.UseSwaggerUI();
}
...

在.net core 3.1 和.net5 都运行好好的,在.net6就报异常:

InvalidOperationException: Cannot modify ServiceCollection after application is built.

System.InvalidOperationException: Cannot modify ServiceCollection after application is built.
at Microsoft.AspNetCore.WebApplicationServiceCollection.CheckServicesAccess()
at Microsoft.AspNetCore.WebApplicationServiceCollection.Add(ServiceDescriptor item)
at Microsoft.Extensions.DependencyInjection.ServiceCollectionServiceExtensions.AddSingleton(IServiceCollection services, Type serviceType, Object implementationInstance)
at Microsoft.Extensions.DependencyInjection.ServiceCollectionServiceExtensions.AddSingleton[TService](IServiceCollection services, TService implementationInstance)
at Microsoft.Extensions.DependencyInjection.OptionsServiceCollectionExtensions.Configure[TOptions](IServiceCollection services, String name, Action`1 configureOptions)
at Microsoft.Extensions.DependencyInjection.OptionsServiceCollectionExtensions.Configure[TOptions](IServiceCollection services, Action`1 configureOptions)
at Unchase.Swashbuckle.AspNetCore.Extensions.Extensions.SwaggerGenOptionsExtensions.AddEnumsWithValuesFixFilters(SwaggerGenOptions swaggerGenOptions, IServiceCollection services, Action`1 configureOptions)
at WebApi6._0.Bootstrapper.<>c__DisplayClass0_0.<AddSwagger>b__0(SwaggerGenOptions c) in D:\learn\netcoreTest\WebApi6.0\Bootstrapper.cs:line 32
at Microsoft.Extensions.Options.ConfigureNamedOptions`1.Configure(String name, TOptions options)
at Microsoft.Extensions.Options.OptionsFactory`1.Create(String name)
at Microsoft.Extensions.Options.UnnamedOptionsManager`1.get_Value()
at Swashbuckle.AspNetCore.SwaggerGen.ConfigureSwaggerGeneratorOptions..ctor(IOptions`1 swaggerGenOptionsAccessor, IServiceProvider serviceProvider, IWebHostEnvironment hostingEnv)
at System.RuntimeMethodHandle.InvokeMethod(Object target, Span`1& arguments, Signature sig, Boolean constructor, Boolean wrapExceptions)
at System.Reflection.RuntimeConstructorInfo.Invoke(BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)
at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitConstructor(ConstructorCallSite constructorCallSite, RuntimeResolverContext context)
at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteVisitor`2.VisitCallSiteMain(ServiceCallSite callSite, TArgument argument)
at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteVisitor`2.VisitCallSite(ServiceCallSite callSite, TArgument argument)
at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitIEnumerable(IEnumerableCallSite enumerableCallSite, RuntimeResolverContext context)
at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteVisitor`2.VisitCallSiteMain(ServiceCallSite callSite, TArgument argument)
at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteVisitor`2.VisitCallSite(ServiceCallSite callSite, TArgument argument)
at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitConstructor(ConstructorCallSite constructorCallSite, RuntimeResolverContext context)
at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteVisitor`2.VisitCallSiteMain(ServiceCallSite callSite, TArgument argument)
at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteVisitor`2.VisitCallSite(ServiceCallSite callSite, TArgument argument)
at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitConstructor(ConstructorCallSite constructorCallSite, RuntimeResolverContext context)
at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteVisitor`2.VisitCallSiteMain(ServiceCallSite callSite, TArgument argument)
at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitRootCache(ServiceCallSite callSite, RuntimeResolverContext context)
at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteVisitor`2.VisitCallSite(ServiceCallSite callSite, TArgument argument)
at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.Resolve(ServiceCallSite callSite, ServiceProviderEngineScope scope)
at Microsoft.Extensions.DependencyInjection.ServiceProvider.CreateServiceAccessor(Type serviceType)
at System.Collections.Concurrent.ConcurrentDictionary`2.GetOrAdd(TKey key, Func`2 valueFactory)
at Microsoft.Extensions.DependencyInjection.ServiceProvider.GetService(Type serviceType, ServiceProviderEngineScope serviceProviderEngineScope)
at Microsoft.Extensions.DependencyInjection.ServiceLookup.ServiceProviderEngineScope.GetService(Type serviceType)
at Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService(IServiceProvider provider, Type serviceType)
at Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService[T](IServiceProvider provider)
at Microsoft.Extensions.DependencyInjection.SwaggerGenServiceCollectionExtensions.<>c.<AddSwaggerGen>b__0_1(IServiceProvider s)
at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteVisitor`2.VisitCallSiteMain(ServiceCallSite callSite, TArgument argument)
at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteVisitor`2.VisitCallSite(ServiceCallSite callSite, TArgument argument)
at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitConstructor(ConstructorCallSite constructorCallSite, RuntimeResolverContext context)
at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteVisitor`2.VisitCallSiteMain(ServiceCallSite callSite, TArgument argument)
at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteVisitor`2.VisitCallSite(ServiceCallSite callSite, TArgument argument)
at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.Resolve(ServiceCallSite callSite, ServiceProviderEngineScope scope)
at Microsoft.Extensions.DependencyInjection.ServiceLookup.DynamicServiceProviderEngine.<>c__DisplayClass2_0.<RealizeService>b__0(ServiceProviderEngineScope scope)
at Microsoft.Extensions.DependencyInjection.ServiceProvider.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_method1(Closure , Object , HttpContext , IServiceProvider )
at Microsoft.AspNetCore.Builder.UseMiddlewareExtensions.<>c__DisplayClass5_1.<UseMiddleware>b__2(HttpContext context)
at Microsoft.AspNetCore.Routing.EndpointRoutingMiddleware.Invoke(HttpContext httpContext)
at Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddleware.Invoke(HttpContext context)

下了源码下来发现,问题应该出现在这行:

...
c.AddEnumsWithValuesFixFilters(services, o =>
{
o.IncludeDescriptions = true;
o.IncludeXEnumRemarks = true;
o.DescriptionSource = DescriptionSources.DescriptionAttributesThenXmlComments;
o.IncludeXmlCommentsFrom(apiXmlPath);
});
...

对应nuget源码的这行:

   if (configureOptions != null)
{
services?.Configure(configureOptions);
}

https://github.com/unchase/Unchase.Swashbuckle.AspNetCore.Extensions/blob/d710cb6557944c49824d0cb31b72b90ad0319c1f/src/Unchase.Swashbuckle.AspNetCore.Extensions/Extensions/SwaggerGenOptionsExtensions.cs#L82

原因是:.net6之后已经不允许在

var app = builder.Build();

app build后再做 services?.Configure()操作

那简单;

解决

思路是,先在build操作之前就把services?.Configure()这种操作写好

所以我这里的写法可以改为:

1、先更换引用的nuget包(因为在作者修改这个问题前暂时打了一个自己的nuget)

<PackageReference Include="Unchase.Swashbuckle.AspNetCore.Extensions" Version="2.6.12" />

//改为
<PackageReference Include="Hei.Unchase.Swashbuckle.AspNetCore.Extensions" Version="2.6.12.1" />

2、上面代码改为:

var apiXmlPath = Path.Combine(AppContext.BaseDirectory, $"{Assembly.GetExecutingAssembly().GetName().Name}.xml");
//这里提前
var action = new Action<FixEnumsOptions>(o =>
{
o.IncludeDescriptions = true;
o.IncludeXEnumRemarks = true;
o.DescriptionSource = DescriptionSources.DescriptionAttributesThenXmlComments;
o.IncludeXmlCommentsFrom(apiXmlPath);
}); services.AddSwaggerGen(c =>
{
//文档
c.SwaggerDoc("v1", new OpenApiInfo
{
Title = "『xxx』后端接口:myapi",
Version = "v1",
});
c.SwaggerDoc("v2", new OpenApiInfo { Title = "v2", Version = "v2" });
c.SwaggerDoc("v3", new OpenApiInfo { Title = "v3", Version = "v3" });
c.SwaggerDoc("v4", new OpenApiInfo { Title = "华为服务号相关/健康币", Version = "v4" });
c.MapType<long>(() => new OpenApiSchema { Type = "string" });
c.IncludeXmlComments(apiXmlPath);
c.DescribeAllParametersInCamelCase();
//这里改为
c.AddEnumsWithValuesFixFilters(action);
});

问题解决!

总结

在同样.net6报这个错的时候注意看看:没页面先在build操作之前就把services?.Configure()这种操作写好

InvalidOperationException Cannot modify ServiceCollection after application is built .Net6 异常的更多相关文章

  1. webservice有关application/xop+xml的异常

    今天同事调用一个webservice时返回类似错误 响应消息的内容类型 multipart/related; type="application/xop+xml"; boundar ...

  2. idea application.properties图标显示异常(无小树叶)

    项目中(多级模块)如果没有主启动类时,新建的application.properties文件显示图标是文本格式图标,就如第一张图所示 添加该项目该模块下主启动类,就可以解决图标显示问题,也就可以看到可 ...

  3. MasaFramework的MinimalAPI设计

    在以前的MVC引用程序中,控制器负责接收输入信息.执行.编排操作并返回响应,它是一个功能齐全的框架,它提供了过滤器.内置了模型绑定与验证,并提供了很多可扩展的管道,但它偏重,不像其它语言是通过更加简洁 ...

  4. How to modify a compiled Android application (.apk file)

    Today I’d like to share with you my findings about how an existing .apk file can be modified. An .ap ...

  5. Understanding and Analyzing Application Crash Reports

    Introduction When an application crashes, a crash report is created and stored on the device. Crash ...

  6. [转]Creating an Entity Framework Data Model for an ASP.NET MVC Application (1 of 10)

    本文转自:http://www.asp.net/mvc/overview/older-versions/getting-started-with-ef-5-using-mvc-4/creating-a ...

  7. SilverLight抛出 System.InvalidOperationException: 超出了2083 的最大URI

    在SilverLight中对于抛出 System.InvalidOperationException: 超出了 2083 的最大 URI 长度 的异常 处理 其实很简单 在 EntityFramewo ...

  8. WPF入口Application

    1.WPF和 传统的WinForm 类似, WPF 同样需要一个 Application 来统领一些全局的行为和操作,并且每个 Domain (应用程序域)中只能有一个 Application 实例存 ...

  9. [转]WPF入口Application

    1.WPF和 传统的WinForm 类似, WPF 同样需要一个 Application 来统领一些全局的行为和操作,并且每个 Domain (应用程序域)中只能有一个 Application 实例存 ...

  10. Java性能提示(全)

    http://www.onjava.com/pub/a/onjava/2001/05/30/optimization.htmlComparing the performance of LinkedLi ...

随机推荐

  1. VisualStudio 在 DebuggerDisplay 的属性更改业务逻辑将会让调试和非调试下逻辑不同

    本文记录我写的逗比代码,我在 DebuggerDisplay 对应的属性的 get 方法上,在这个方法里面修改了业务逻辑,如修改界面元素,此时我在 VisualStudio 断点调试下和非断点调试下的 ...

  2. java 高并发下超购问题解决

    //@desc:java 高并发下锁机制初探 //@desc:码字不宜,转载请注明出处 //@author:张慧源  <turing_zhy@163.com> //@date:2021/1 ...

  3. 简说Python之flask初体验

    目录 flask初体验 1.安装Flask 2.创建"Hello, World" Flask应用 3.执行结果 flask是python web的轻量框架,简单的几条命令就可以创建 ...

  4. 一键接入大模型:One-Api本地安装配置实操

    前言 最近准备学习一下 Semantic Kernel, OpenAI 的 Api 申请麻烦,所以想通过 One-api 对接一下国内的在线大模型,先熟悉一下 Semantic Kernel 的基本用 ...

  5. three.js教程5-几何体顶点UV坐标、纹理贴图TextureLoader

    1.纹理贴图 纹理贴图,是给MeshLambertMaterial等材质一些纹理图片,以达到更好的视觉效果. 使用方法:通过纹理贴图加载器TextureLoader的load()方法加载一张图片可以返 ...

  6. leaflet叠加图片图层

    <!DOCTYPE html> <html> <head> <title>Layers Control Tutorial - Leaflet</t ...

  7. Django国际化与本地化指南

    title: Django国际化与本地化指南 date: 2024/5/12 16:51:04 updated: 2024/5/12 16:51:04 categories: 后端开发 tags: D ...

  8. ETSI GS MEC 013,UE 位置 API

    目录 文章目录 目录 版本 功能理解 Relation with OMA APIs Relation with OMA API for Zonal Presence Relation with OMA ...

  9. 使用systemctl管理服务(nginx)

    首先调整好路径信息,修改配置文件vim /usr/lib/systemd/system/nginx.service [Unit]Description=The nginx HTTP and rever ...

  10. Machine Learning - 梯度下降

    一.梯度下降:目的是为了寻找到最合适的 $w$ 和 $b$ ,让成本函数的值最小 \[w = w - α\frac{\partial J(w,b)}{\partial w} \] \[b = b - ...