发布ASP.Net Core至IIS触发“值不能为空”错误排查
看起来你遇到的问题核心是手动干预了ASP.NET Core内置的日志系统依赖注入注册,加上InProcess托管模式下的生命周期冲突,导致DI容器在初始化时找不到正确的实例,抛出ArgumentNullException。咱们一步步来修复:
1. 移除手动的LoggerFactory静态字段和Logger实例化
你的Startup类里定义了静态的LoggerFactory和AppLogger,还手动调用LoggerFactory.CreateLogger——这时候DI容器还没完成初始化,LoggerFactory其实是null,这直接导致了后续的注入错误。ASP.NET Core已经内置了日志服务的注册,不需要手动创建和维护这些静态对象。
修改Startup类的相关代码:
public class Startup { // 移除这些静态字段 // public static ILoggerFactory LoggerFactory = null; // public static ILogger<ConsoleLoggerProvider> AppLogger = null; public IConfiguration Configuration { get; } // 保留构造函数,只注入IConfiguration即可(ILoggerFactory会由DI自动注入,不需要在构造函数里显式声明) public Startup(IConfiguration configuration) { Configuration = configuration; } public void ConfigureServices(IServiceCollection services) { // 保留日志配置,但移除手动创建Logger的代码 services.AddLogging(builder => builder .AddConfiguration(Configuration.GetSection("Logging")) .AddConsole() .AddDebug() ); // 移除这两行手动注册ILoggerFactory和ILogger<>的代码,ASP.NET Core已经自动注册了 // services.TryAdd(ServiceDescriptor.Singleton<ILoggerFactory, LoggerFactory>()); // services.TryAdd(ServiceDescriptor.Singleton(typeof(ILogger<>), typeof(Logger<>))); // ... 其他代码 } }
2. 修复AuthSettings的注册方式
你手动用Options.Create然后取Value的方式是多余的,而且可能导致配置绑定错误。直接让DI容器来处理配置绑定:
替换原来的AuthSettings注册代码:
// 原来的错误写法 // AuthSettings _authSettings = new AuthSettings(); // _authSettings = Options.Create<AuthSettings>(Configuration.GetSection("AuthSettings").Get<AuthSettings>()).Value; // services.AddSingleton<AuthSettings>(_authSettings); // 正确写法:让DI自动绑定配置并注册为单例 services.Configure<AuthSettings>(Configuration.GetSection("AuthSettings")); // 如果需要直接注入AuthSettings而不是IOptions<AuthSettings>,可以这样: services.AddSingleton(sp => sp.GetRequiredService<IOptions<AuthSettings>>().Value);
3. 检查IIS托管模式和应用池配置
你的web.config里设置了hostingModel="InProcess",而应用池配置为“无托管代码”——这是正确的,因为InProcess模式下ASP.NET Core应用直接在IIS进程内运行,不需要托管代码支持。不过可以确认一下:
- 确保服务器安装了ASP.NET Core Hosting Bundle,这是运行ASP.NET Core应用在IIS上的必要组件
- 检查stdout日志(你已经开启了
stdoutLogEnabled="true"),.\logs\stdout目录下的日志会给出更详细的启动错误信息,帮助排查剩余问题
4. 验证CookiePolicyOptions的配置
原来报错的services.Configure<CookiePolicyOptions>代码本身没问题,但之前的DI混乱导致它无法正常执行。修复上述问题后,这段代码应该可以正常运行:
services.Configure<CookiePolicyOptions>(options => { options.CheckConsentNeeded = context => true; options.MinimumSameSitePolicy = SameSiteMode.None; });
总结
本质问题是你手动接管了ASP.NET Core内置的日志服务注册,导致DI容器在启动时无法正确解析依赖。移除这些手动操作,让DI容器自动管理日志和配置对象,就能解决启动时的ArgumentNullException。
内容的提问来源于stack exchange,提问作者Phil Huhn

