背景

我用了一个叫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. 实验8 #第8章 Verilog有限状态机设计-1 #Verilog #Quartus #modelsim

    8-1 流水灯控制器 1. 实验要求:采用有限状态机设计彩灯控制器,控制LED灯实现预想的演示花型. 2. 实验内容: (1)功能:设计彩灯控制器,要求控制18个LED灯实现如下的演示花型: 从两边往 ...

  2. 关于SQL数据库Varchar字符串类型长度设计问题(转载)

    为什么要合理的设计数据库字段数据类型的长度?个人观点:一个是降低物理上的存储空间,一个是提高数据库的处理速度,还有一个附带功能是能校验数据是否合法.   现代数据库一般都支持CHAR与VARCHAR字 ...

  3. C语言:如何实现在txt文件中删除超链接、统计单词数量、生成单词列表 (文本流操作并解决乱码)

    1.首先读取原文件内容文本流(包含中英文) 2.删除超链接 3.统计单词数量 4.去除重复单词 读取文件需要自己在文本笔记中保存一个网页,保存为txt文件 注意的是,在这个代码实现过程中,我学到的是如 ...

  4. IPv6 — 地址格式与寻址模式

    目录 文章目录 目录 前文列表 IPv6 的地址格式 站点前缀 地址生成方式 IPv6 地址的分类以及寻址模式 单播(Unicast)地址 Interface ID 全球唯一地址(Global Uni ...

  5. Windows Server 2022 初始设置

    添加本地用户 添加新的本地用户. 在CUI配置上,按如下方式设置. 使用管理员权限运行 PowerShell 并按如下方式进行配置. Windows PowerShell 版权所由 (C) Micro ...

  6. 创建Django项目和应用

    1.创建Django项目 django-admin startproject 项目名称 2.创建应用app python manage.py startapp app名称

  7. Android 12(S) MultiMedia(十四)ESQueue

    之前看到在ATSParser::Pogram::Stream中会创建一个ESQueue,用于存储解析出来的ES data,这个ESQueue到底是用来做什么的呢?这节就来研究研究. 1.构造函数 ES ...

  8. Maven工程报错org.codehaus.plexus.component.repository.exception.ComponentLookupException

    本人电脑环境:jdk1.8,idea2021,maven 3.6.3 问题:今天调整maven项目的三个配置参数后,idea报了下面的错误 org.codehaus.plexus.component. ...

  9. java中判断String类型为空和null的方法

    1.判断一个String类型的变量是否为空(即长度为0)或者为null 在Java中,判断一个String类型的变量是否为空(即长度为0)或者为null,通常需要使用两个条件语句来进行检查.这是因为n ...

  10. Vue渲染函数与JSX指南

    title: Vue渲染函数与JSX指南 date: 2024/6/3 下午6:43:53 updated: 2024/6/3 下午6:43:53 categories: 前端开发 tags: Vue ...