.NET 6升级.NET 8后触发InvalidOperationException问题求助
非重复问题
本问题并非《服务集合无法修改,因为它是只读的》的重复问题:我的代码中并未在var app = builder.Build();之后对builder.Services进行任何操作
问题描述
我正在将一个C#编写的ASP.NET Core Web API项目从.NET 6升级到.NET 8。我仅做了如下修改:
<PropertyGroup> <TargetFramework>net6.0</TargetFramework> <Nullable>enable</Nullable> <ImplicitUsings>enable</ImplicitUsings> <Configurations>Debug;Release;StoutBI;UAT</Configurations> </PropertyGroup>
修改为
<TargetFramework>net8.0</TargetFramework>
在我们升级的其他项目中,这样的修改足以让项目编译并正常运行。
但在本项目中,代码可以编译,但每次调用端点时都会触发以下异常:
System.InvalidOperationException: The service collection cannot be modified because it is read-only.
at Microsoft.Extensions.DependencyInjection.ServiceCollection.ThrowReadOnlyException()
at Microsoft.Extensions.DependencyInjection.ServiceCollection.System.Collections.Generic.ICollection<Microsoft.Extensions.DependencyInjection.ServiceDescriptor>.Add(ServiceDescriptor item)
at Microsoft.Extensions.DependencyInjection.ServiceCollectionServiceExtensions.AddTransient(IServiceCollection services, Type serviceType, Type implementationType)
at Microsoft.Extensions.DependencyInjection.OptionsBuilderExtensions.ValidateOnStart[TOptions](OptionsBuilder1 optionsBuilder) at Microsoft.Extensions.DependencyInjection.MetricsServiceExtensions.AddMetrics(IServiceCollection services) at Microsoft.Extensions.DependencyInjection.HttpClientFactoryServiceCollectionExtensions.AddHttpClient(IServiceCollection services) at Microsoft.Identity.Web.MicrosoftIdentityWebAppAuthenticationBuilderWithConfiguration.<EnableTokenAcquisitionToCallDownstreamApi>b__1_0(ConfidentialClientApplicationOptions options) at Microsoft.Extensions.Options.OptionsFactory1.Create(String name)
at System.Lazy1.ViaFactory(LazyThreadSafetyMode mode) at System.Lazy1.ExecutionAndPublication(LazyHelper executionAndPublication, Boolean useDefaultConstructor)
at System.Lazy1.CreateValue() at Microsoft.Extensions.Options.OptionsCache1.GetOrAdd[TArg](String name, Func3 createOptions, TArg factoryArgument) at Microsoft.Extensions.Options.OptionsMonitor1.Get(String name)
at Microsoft.Identity.Web.MicrosoftIdentityWebAppAuthenticationBuilder.<>c__DisplayClass11_0.b__0(OpenIdConnectOptions options, IMergedOptionsStore mergedOptionsMonitor, IOptionsMonitor1 ccaOptionsMonitor, IOptions1 ccaOptions)
at Microsoft.Extensions.Options.ConfigureNamedOptions4.Configure(String name, TOptions options) at Microsoft.Extensions.Options.OptionsFactory1.Create(String name)
at System.Lazy1.ViaFactory(LazyThreadSafetyMode mode) --- End of stack trace from previous location --- at System.Lazy1.CreateValue()
at Microsoft.Extensions.Options.OptionsCache1.GetOrAdd[TArg](String name, Func3 createOptions, TArg factoryArgument)
at Microsoft.Extensions.Options.OptionsMonitor1.Get(String name)<br /> at Microsoft.AspNetCore.Authentication.AuthenticationHandler1.InitializeAsync(AuthenticationScheme scheme, HttpContext context)
at Microsoft.AspNetCore.Authentication.AuthenticationHandlerProvider.GetHandlerAsync(HttpContext context, String authenticationScheme)
at Microsoft.AspNetCore.Authentication.AuthenticationMiddleware.Invoke(HttpContext context)
at Swashbuckle.AspNetCore.SwaggerUI.SwaggerUIMiddleware.Invoke(HttpContext httpContext)
at Swashbuckle.AspNetCore.Swagger.SwaggerMiddleware.Invoke(HttpContext httpContext, ISwaggerProvider swaggerProvider)
at Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddlewareImpl.Invoke(HttpContext context)
根据调用的端点不同,堆栈跟踪会略有差异,但异常始终相同(--- End of stack trace from previous location ---以上的部分)。
.NET 8在应用构建和配置方式上是否有变化?或者相关库的设置方式发生了改变?
以下是我Program.cs中的核心代码(与.NET 6时一致):
DbContextOptionsBuilder<ReadWriteContext> optionsBuilder = new DbContextOptionsBuilder<ReadWriteContext>(); optionsBuilder.UseSqlServer(InternalApiUtil.DbConnectionString); // Add manually constructed DbContext builder.Services.AddScoped(sp => new ReadWriteContext(optionsBuilder.Options)); builder.Services.AddScoped<UserService, UserService>(); builder.Services.AddScoped<IChartsService, ChartsService>(); builder.Services.AddControllers(options => { options.Filters.Add<GlobalActionFilter>(); }).AddJsonOptions(options => { options.JsonSerializerOptions.PropertyNamingPolicy = JsonNamingPolicy.CamelCase; options.JsonSerializerOptions.DictionaryKeyPolicy = JsonNamingPolicy.CamelCase; }); builder.Services.AddCors(options => { options.AddPolicy(CORS_POLICY_NAME, builder => { builder.AllowAnyOrigin().AllowAnyHeader().AllowAnyMethod(); }); }); builder.Services.AddEndpointsApiExplorer(); // 尝试过注释掉该行,无变化 builder.Services.AddSwaggerGen(); builder.Services.AddScoped(typeof(IGenericRepository<>), typeof(GenericRepository<>)); builder.Services.AddScoped(typeof(MyCacheService<>)); builder.Services.AddMemoryCache(opt => { opt.SizeLimit = 1024; }); builder.Services.AddAutoMapper(ProfileFactory.CustomProfiles); string[] initialScopes = { "Group.Read.All", "User.Read.All" }; IConfigurationSection azureAd = builder.Configuration.GetSection("AzureAd"); builder.Services.AddAuthentication() .AddJwtBearer() .AddMicrosoftIdentityWebApp(azureAd) .EnableTokenAcquisitionToCallDownstreamApi(initialScopes) .AddMicrosoftGraph() .AddInMemoryTokenCaches(); var app = builder.Build(); if (app.Environment.IsDevelopment()) { app.UseSwagger(); app.UseSwaggerUI(); } app.UseHttpsRedirection(); app.UseDefaultFiles(); app.UseStaticFiles(); app.UseCors(CORS_POLICY_NAME); app.UseAuthentication(); app.UseAuthorization(); app.MapControllers(); #if DEBUG app.Run(InternalApiUtil.LOCAL_SERVER_URL); #else app.Run(); #endif if (baseRule != null && InternalApiUtil.LogDebugStatements) { baseRule.EnableLoggingForLevel(NLog.LogLevel.Debug); } logger.Info("Ready to run.");
我是在DEBUG模式下运行代码时出现这些错误的。测试/生产部署中使用Easy Auth。
已尝试的其他方法
- 未手动修改,改用.NET升级助手,但它做的修改完全相同。
- 按照NuGet提示升级了所有包,结果依旧。
内容的提问来源于stack exchange,提问作者markvgti

