从appsettings.json文件中读取NullReferance错误

时间:2016-02-04 16:03:04

标签: c# asp.net-core-mvc

我正在尝试从我的appsettings.json文件中读取一些设置,但我正在获取NullReferenceException。使用不同的SO帖子以及我在谷歌上发现的一些博客我构建了代码,这一切看起来都是正确的,没有编译错误和intillisense一切正常,所以我不确定我错过了什么或做错了。

Startup.CS:

public class Startup
{
    public IConfigurationRoot Configuration { get; set; }

    public Startup(IHostingEnvironment env)
    {
        //Set up configuration sources.
        var builder = new ConfigurationBuilder()
            .AddJsonFile("appsettings.json")
            .AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true)
            .AddEnvironmentVariables();

        Configuration = builder.Build();
    }

    // This method gets called by the runtime. Use this method to add services to the container.
    public void ConfigureServices(IServiceCollection services)
    {
        services.AddMvc();
        services.AddCaching();
        services.Configure<ApplicationSettingsModel>(Configuration.GetSection("AppSettings"));
        services.AddScoped<IApplicationSettings, ApplicationSettings>();

        services.AddSession(o =>
        {
            o.IdleTimeout = TimeSpan.FromSeconds(10);
        });
    }

    // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
    public void Configure(IApplicationBuilder app, IHostingEnvironment env)
    {
        if (env.IsDevelopment())
        {
            app.UseDeveloperExceptionPage();
        }

        app.UseExceptionHandler("/Error/ServerError");
        app.UseIISPlatformHandler();
        app.UseSession();
        app.UseStaticFiles();
        app.UseStatusCodePagesWithReExecute("/Error/PageNotFound");
        app.UseMvc();
    }

    // Entry point for the application.
    public static void Main(string[] args) => WebApplication.Run<Startup>(args);
}

IApplicationSettings:

public interface IApplicationSettings
{
    IOptions<ApplicationSettingsModel> AppSettings { get; }
}

ApplicationsSettings.cs:

public class ApplicationSettings : IApplicationSettings
{
    protected readonly IOptions<ApplicationSettingsModel> _AppSettings;

    public ApplicationSettings(IOptions<ApplicationSettingsModel> AppSettings)
    {
        _AppSettings = AppSettings;
    }

    public IOptions<ApplicationSettingsModel> AppSettings
    {
        get
        {
            return _AppSettings;
        }
    }

    public string GetAppVersion()
    {
        return _AppSettings.Value.AppVersion;
    }
}

型号:

public class ApplicationSettingsModel
{
    public string AppVersion { get; set; }
    public string BugZillaAPIKey { get; set; }
    public string EmailUser { get; set; }
    public string EmailPass { get; set; }
}

拨打电话的班级:

public class EHAL
{
    private static IApplicationSettings _config;

    public EHAL(IApplicationSettings config)
    {
        _config = config;
    }

    public static string Test()
    {
        return _config.AppSettings.Value.AppVersion;
    }
}

当我尝试运行return _AppSettings.Value.AppVersion;时出现错误。从SO帖子和博客我觉得我做的一切都很正确,但很明显我搞砸了什么,只是不确定是什么。

1 个答案:

答案 0 :(得分:1)

我不是100%确定你到底想要做什么,但你应该能够让DI容器处理构造函数注入,我做了一个小测试应用程序来注入test类进入控制器,例如....

将您的测试类更改为

public class test : Itest
{
    protected readonly IOptions<AppSettings> _AppSettings;

    public test(IOptions<AppSettings> AppSettings)
    {
        _AppSettings = AppSettings;
    }

    public IOptions<AppSettings> AppSettings
    {
        get
        {
            return _AppSettings;
        }
    }

    public string GetAppVersion()
    {
        return _AppSettings.Value.AppVersion;
    }
}

添加界面Itest

public interface Itest
{
    IOptions<AppSettings> AppSettings { get; }
}

在Startup.cs中添加一个新行

services.Configure<AppSettings>(Configuration.GetSection("AppSettings"));
services.AddScoped<Itest, test>();

现在,您可以在控制器中执行以下操作:

 public class HomeController : Controller
    {
        private readonly Itest _config;
        public HomeController(Itest config)
        {
            _config = config;
        }
        public IActionResult Index()
        {
            var a = _config.AppSettings.Value.AppVersion;
            return View();
        }
    }

只会将测试类的实例注入控制器,以便在处理请求时使用它。

同样,不是100%确定你要去哪里,这是一个如何使这个工作的例子。希望有所帮助!

编辑:您还有其他一些选项,您可以将IOptions<AppSettings>注入控制器构造函数,并创建一个传入注入的IOptions<AppSettings>的测试类实例。这样你就可以摆脱Starts.cs中的Itest接口和额外的配置代码,只是另一种想法。

编辑: 所以,我真的认为你应该看看依赖注入,它真的是要走的路。但如果你真的不想去DI根,你可以这样做,(改变你的静态类看起来像这样):

public class test
{
    static IConfigurationSection _Settings;

    static test()
    {

        IConfiguration _config = new ConfigurationBuilder()
            .AddJsonFile("appsettings.json")
            .Build();

        _Settings = _config.GetSection("AppSettings");
    }

    public static string GetAppVersion()
    {
        return _Settings["AppVersion"];
    }
}

然后你可以这样打电话:

var a = test.GetAppVersion();

虽然我不喜欢用静力学做这件事,但我试图保持你想要做的精神。真的,DI是前进的方式,强烈建议你将来朝这个方向发展。