关键词 System.ArgumentNullException: String reference not set to an instance of a String. (Parameter 's')

1. 问题出现

某年某月某日,把webapi开发完了,也通过了swagger进行了单元测试。

dotnet build
dotnet publish -o publish
dotnet .\publish\xx.Webapi.dll

然后 String reference not set to an instance of a String. (Parameter 's')

fail: Microsoft.AspNetCore.Diagnostics.ExceptionHandlerMiddleware[1]
      An unhandled exception has occurred while executing the request.
System.ArgumentNullException: String reference not set to an instance of a String. (Parameter 's')
   at System.Text.Encoding.GetBytes(String s)
   at AliMobilePush.Webapi.Startup.<ConfigureServices>b__5_2(JwtBearerOptions option) in E:\工作事项\code\dev-push\Alipush\AliMobilePush.Webapi\Startup.cs:line 75
   at Microsoft.Extensions.Options.ConfigureNamedOptions`1.Configure(String name, TOptions options)
   at Microsoft.Extensions.Options.OptionsFactory`1.Create(String name)
   at Microsoft.Extensions.Options.OptionsMonitor`1.<>c__DisplayClass11_0.<Get>b__0()
   at System.Lazy`1.ViaFactory(LazyThreadSafetyMode mode)
   at System.Lazy`1.ExecutionAndPublication(LazyHelper executionAndPublication, Boolean useDefaultConstructor)
   at System.Lazy`1.CreateValue()
   at System.Lazy`1.get_Value()
   at Microsoft.Extensions.Options.OptionsCache`1.GetOrAdd(String name, Func`1 createOptions)
   at Microsoft.Extensions.Options.OptionsMonitor`1.Get(String name)
   at Microsoft.AspNetCore.Authentication.AuthenticationHandler`1.InitializeAsync(AuthenticationScheme scheme, HttpContext context)
   at Microsoft.AspNetCore.Authentication.AuthenticationHandlerProvider.GetHandlerAsync(HttpContext context, String authenticationScheme)
   at Microsoft.AspNetCore.Authentication.AuthenticationService.AuthenticateAsync(HttpContext context, String scheme)
   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.ExceptionHandlerMiddleware.<Invoke>g__Awaited|6_0(ExceptionHandlerMiddleware middleware, HttpContext context, Task task)

配置文件读出来为null,为什么?

2. 难道是非管理员, 权限不够?

切换至管理员,运行上述命令,还是报错。

3. 无意间解决

cd publish
dotnet xx.Webapi.dll

就能读到了,这是为什么,根据上述命令的差异,大概能猜测到应该是路径不同,导致读取 appsetting.json 失败。

4. 原来是这样

dotnet run ,应该会根据 env.ContentRootPath (env 的类型是IHostingEnvironment )来读取配置文件 appsettings.Production.jsonappsettings.json 文件, ContentRootPath 属性得到的值为当前启动命令的目录,而不是dll所在的目录,所以应在发布项目 dll 所在的目录执行 dotnet xx.dll ,否则会导致配置文件里面的参数读取不到。请看源码和命令对比:

// Host. CreateDefaultBuilder(args)

//源码Host.cs
builder. ConfigureAppConfiguration((hostingContext, config) =>

            {
                var env = hostingContext.HostingEnvironment;

                config.AddJsonFile("appsettings.json", optional: true, reloadOnChange: true)
                      .AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true, reloadOnChange: true);

                if (env.IsDevelopment() && !string.IsNullOrEmpty(env.ApplicationName))
                {
                    var appAssembly = Assembly.Load(new AssemblyName(env.ApplicationName));
                    if (appAssembly != null)
                    {
                        config.AddUserSecrets(appAssembly, optional: true);
                    }
                }

                config.AddEnvironmentVariables();

                if (args != null)
                {
                    config.AddCommandLine(args);
                }
            })

image-20200601233212378

image-20200601233251700

5. 参考链接

https://www.cnblogs.com/DHclly/p/9606866.html

https://www.netnr.com/home/list/115

https://github.com/dotnet/extensions.git

https://my.oschina.net/u/4364008/blog/3205437