升级至.NET 7后ASP.NET Core MVC应用无法运行,求问题排查
我把ASP.NET MVC 2.2应用升级到ASP.NET Core 7 MVC后,应用无法正常运行。以下是我的startup.cs代码,麻烦帮我看看哪里出错了?
public IServiceProvider ConfigureServices(IServiceCollection services) { services .AddAntiforgery(options => options.HeaderName = "XSRF-TOKEN") .AddControllers(options => { options.CacheProfiles.Add("DefaultNoCacheProfile", new CacheProfile { NoStore = true, Location = ResponseCacheLocation.None }); options.Filters.Add(new ResponseCacheAttribute { CacheProfileName = "DefaultNoCacheProfile" }); var sp = services.BuildServiceProvider(); /* Here getting a Warning ASP0000 Calling 'BuildServiceProvider' from application code results in an additional copy of singleton services being created. Consider alternatives such as dependency injecting services as parameters to 'Configure' */ return sp; } public void Configure(IApplicationBuilder app, IHostEnvironment env) { // app.UseSession(); app.UseAuthentication(); if (env.IsDevelopment()) { app.UseDeveloperExceptionPage(); } else { app.UseExceptionHandler("/Home/Error"); } app.UseMiddleware<HttpRequestWare>(_container); app.UseStaticFiles(); app.UseCookiePolicy(new CookiePolicyOptions { MinimumSameSitePolicy = SameSiteMode.Strict, }); var environment = _config["Environment"]; if (environment == EnvironmentType.Live.ToString()) { var supportedCultures = new[] { new CultureInfo("en-US") }; app.UseRequestLocalization(new RequestLocalizationOptions { SupportedCultures = supportedCultures, SupportedUICultures = supportedCultures, RequestCultureProviders = new List<IRequestCultureProvider> { new AcceptLanguageHeaderRequestCultureProvider() } }); } //app.UseMvc(); app.UseRouting(); app.UseEndpoints(endpoints => { endpoints.MapDefaultControllerRoute(); endpoints.MapControllerRoute("default", "{controller=Account}/{action=login}/{id?}"); endpoints.MapControllerRoute("api", "{controller}/{action}/{id?}"); }); }
收到的警告信息:
警告 ASP0000 从应用代码中调用‘BuildServiceProvider’会导致创建单例服务的额外副本。
请考虑替代方案,例如将服务作为参数依赖注入到‘Configure’中
主要问题及修复方案
1. 错误手动构建服务提供者
ASP.NET Core框架会自动处理服务容器的构建,不需要在ConfigureServices中手动调用BuildServiceProvider并返回IServiceProvider。这种写法会导致单例服务被实例化两次,触发ASP0000警告,还可能引发依赖注入逻辑混乱。
修复:
将ConfigureServices返回类型改为void,移除手动构建代码,同时补上原代码中缺失的AddControllers闭合大括号:
public void ConfigureServices(IServiceCollection services) { services .AddAntiforgery(options => options.HeaderName = "XSRF-TOKEN") .AddControllers(options => { options.CacheProfiles.Add("DefaultNoCacheProfile", new CacheProfile { NoStore = true, Location = ResponseCacheLocation.None }); options.Filters.Add(new ResponseCacheAttribute { CacheProfileName = "DefaultNoCacheProfile" }); }); // 补上缺失的闭合大括号 }
2. 中间件顺序错误
ASP.NET Core中间件顺序直接决定请求处理流程,你的顺序存在多处问题:
UseAuthentication必须放在UseRouting之后、UseEndpoints之前UseRequestLocalization应放在UseStaticFiles之前,确保本地化逻辑覆盖静态资源请求UseCookiePolicy需放在UseAuthentication之前
调整后的Configure方法:
public void Configure(IApplicationBuilder app, IHostEnvironment env, IConfiguration config) { if (env.IsDevelopment()) { app.UseDeveloperExceptionPage(); } else { app.UseExceptionHandler("/Home/Error"); } // 本地化中间件前置 var environment = config["Environment"]; if (environment == EnvironmentType.Live.ToString()) { var supportedCultures = new[] { new CultureInfo("en-US") }; app.UseRequestLocalization(new RequestLocalizationOptions { SupportedCultures = supportedCultures, SupportedUICultures = supportedCultures, RequestCultureProviders = new List<IRequestCultureProvider> { new AcceptLanguageHeaderRequestCultureProvider() } }); } app.UseStaticFiles(); app.UseCookiePolicy(new CookiePolicyOptions { MinimumSameSitePolicy = SameSiteMode.Strict, }); app.UseRouting(); // 认证中间件放在路由之后、端点之前 app.UseAuthentication(); // 若需授权,添加 app.UseAuthorization(); app.UseMiddleware<HttpRequestWare>(_container); app.UseEndpoints(endpoints => { endpoints.MapControllerRoute("default", "{controller=Account}/{action=login}/{id?}"); endpoints.MapControllerRoute("api", "{controller}/{action}/{id?}"); }); }
3. 路由规则冲突
你同时添加了MapDefaultControllerRoute(默认指向Home/Index)和自定义default路由(指向Account/login),两个规则会冲突,建议只保留符合业务需求的一个。
4. 未正确注入依赖
_config和_container需要通过构造函数注入到Startup类,不能直接使用:
private readonly IConfiguration _config; private readonly IServiceProvider _container; public Startup(IConfiguration config, IServiceProvider container) { _config = config; _container = container; }
5. 会话功能(若需启用)
如果应用需要会话,需先在ConfigureServices中添加services.AddSession();,再在Configure中把app.UseSession()放在UseRouting之前、UseStaticFiles之后。
内容的提问来源于stack exchange,提问作者Ertugul

