3

appsettings.json

{
"Logging": {
"IncludeScopes": false,
"LogLevel": {
  "Default": "Verbose",
  "System": "Information",
  "Microsoft": "Information"
},
"CustomSettings": {
  "UseDataCaching": true
  }
 }
}

option class

public class CustomSettings
{
    public bool UseDataCaching { get; set; }
}

startup.cs

 public void ConfigureServices(IServiceCollection services)
    {
        ...
        services.AddOptions();
        services.Configure<CustomSettings>(Configuration);
        ...
    }

    public Startup(IHostingEnvironment env, IApplicationEnvironment appEnv)
    {
        // Set up configuration sources.

        var builder = new ConfigurationBuilder()
            .SetBasePath(appEnv.ApplicationBasePath)
            .AddJsonFile("appsettings.json")
            .AddEnvironmentVariables()
            .AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true);

        if (env.IsDevelopment())
        {
            // For more details on using the user secret store see http://go.microsoft.com/fwlink/?LinkID=532709
            builder.AddUserSecrets();

            // This will push telemetry data through Application Insights pipeline faster, allowing you to view results immediately.
            builder.AddApplicationInsightsSettings(developerMode: true);
        }

        builder.AddEnvironmentVariables();
        Configuration = builder.Build();
    }

controller

 protected IMemoryCache MemoryCache { get; }
    protected IOptions<CustomSettings> CustomSettings { get; set; }
    public HomeController(IMemoryCache cache, IOptions<CustomSettings> customSettings)
    {

        MemoryCache = cache;
        CustomSettings = customSettings;
    }

customSettings.Value.UseDataCaching is always false even though in appsettings.json i have set it to true.

Not sure if i missed something very obvious

EDIT: added startup constructor

USAGE:

     public IActionResult About()
    {
        var isUsingDataCache = CustomSettings.Value.UseDataCaching;
        ViewData["Message"] = "Your application description page.";

        return View();
    }

EDIT: changed the startup to take 2 params

SAMPLE PROJECT DOES NOT WORK http://www.megafileupload.com/a2hn/WebApplication1.zip

Zoinky
  • 4,083
  • 11
  • 40
  • 78

1 Answers1

6

Not sure how are you creating your Configuration object, but make sure you add appsettings.json file in it's pipeline, also add BasePath for your application. For example:

public static IConfigurationRoot Configuration;

// You can use both IHostingEnvironment and IApplicationEnvironment at the same time.
// Instances of them are being injected at runtime by dependency injection.
public Startup(IHostingEnvironment hostingEnv, IApplicationEnvironment appEnv)
{
    // Set up configuration sources.
    var builder = new ConfigurationBuilder()
        .SetBasePath(appEnv.ApplicationBasePath)
        .AddJsonFile("appsettings.json")
        .AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true);

    if (env.IsDevelopment())
    {
        // For more details on using the user secret store see http://go.microsoft.com/fwlink/?LinkID=532709
        builder.AddUserSecrets();

        // This will push telemetry data through Application Insights pipeline faster, allowing you to view results immediately.
        builder.AddApplicationInsightsSettings(developerMode: true);
    }

    builder.AddEnvironmentVariables();
    Configuration = builder.Build();
}

Edit:

Try changing your ConfigureServices method:

services.Configure<CustomSettings>(Configuration); // from this
services.Configure<CustomSettings>(Configuration.GetSection("CustomSettings")); // to this

Edit 2:

Can you try to create your object inside constructor of controller without it being generic type of IOptions like this:

private CustomSettings _customSettings;

public YourControllerName(CustomSettings customSettings)
{
    _customSettings = customSettings;
}

In Startup.cs ConfigureServices method, set:

services.AddSingleton<CustomSettings>();

Then call it like:

public IActionResult About()
{
    var isUsingDataCache = _customSettings.UseDataCaching;
    ViewData["Message"] = "Your application description page.";

    return View();
}

Edit 3:

Your CustomSettings parameter of your json is placed inside Logging parameter. Try changing your json to this:

{
    "Logging": {
        "IncludeScopes": false,
        "LogLevel": {
            "Default": "Verbose",
            "System": "Information",
            "Microsoft": "Information"
        }
    },
    "CustomSettings": {
        "UseDataCaching": true
    }
}

Edit 4:

I actually tried this out. Created fresh new project, replaced default appsettings.json file with data from Edit 3. Inside Startup.cs at the first line of ConfigureServices method I've placed:

public void ConfigureServices(IServiceCollection services)
{
    services.Configure<CustomSettings>(Configuration.GetSection("CustomSettings"));

    ...
}

Finally, I tested it out inside HomeController:

Example

msmolcic
  • 6,407
  • 8
  • 32
  • 56
  • added constructor to original, no i was not missing that part – Zoinky Jan 10 '16 at 03:00
  • @Zoinky I see, can you give me the example where you're trying to read something from your appsettings.json file? – msmolcic Jan 10 '16 at 03:02
  • @Zoinky Can you try setting this part as well ".SetBasePath(appEnv.ApplicationBasePath)". Maybe it's unable to locate your json file because it has no idea where starting point is? – msmolcic Jan 10 '16 at 03:09
  • my startup passes IHostingEnvironment where is yours passes IApplicationEnv.. so i dont get the same properties as you. I am using RC1 is that maybe my problem that it has been updated since? – Zoinky Jan 10 '16 at 03:15
  • @Zoinky I'm also using rc1-final in this project, check my edit. Also, since you're not using IHostingEnvironment, I wonder if you really need it? – msmolcic Jan 10 '16 at 03:22
  • Ya i passed both as you suggested in your edit, same, still result is false – Zoinky Jan 10 '16 at 03:25
  • fyi, i copy pasted your edited method, still comes back as false. – Zoinky Jan 10 '16 at 03:28
  • same result with changing it to services.Configure(Configuration.GetSection("CustomSettings")) – Zoinky Jan 10 '16 at 03:33
  • @Zoinky How are you creating "CustomSettings" variable before you use it like this "CustomSettings.Value.UseDataCaching;". it's weird that you have .Value in it.. – msmolcic Jan 10 '16 at 03:43
  • protected IOptions CustomSettings { get; set; } its a property of my controller and ya the .value comes with it for some reason from the constructor, only way to see it is doing .value – Zoinky Jan 10 '16 at 03:45
  • even put a breakpoint on the controller constructor the variable coming in still has false before i even assign it to the property (also still has .Value) before accessing the class – Zoinky Jan 10 '16 at 03:48
  • casting issue at runtime now InvalidOperationException: Unable to resolve service for type 'blah.UI.Temp.CustomSettings' while attempting to activate 'blah.UI.Controllers.HomeController'. – Zoinky Jan 10 '16 at 04:12
  • @Zoinky Yeah sorry, you need to set dependency injection for it.. check edit 2 updated – msmolcic Jan 10 '16 at 04:22
  • still false.. is something wrong with my appsettings.json – Zoinky Jan 10 '16 at 04:46
  • @Zoinky Haha, actually, yes.. check out 3rd and hopefully final edit.. :) – msmolcic Jan 10 '16 at 04:49
  • @f... no still not working, even changed the property to string – Zoinky Jan 10 '16 at 04:56
  • gonna start a new project, this is garbage – Zoinky Jan 10 '16 at 04:57
  • @Zoinky I'm about to add another edit.. it works for me, not sure why it won't work for you.. – msmolcic Jan 10 '16 at 05:15
  • Can anyone give advice on using this same technique but passing down to a Repository Class Library that needs a ConnectionString? I guess using IOptions constructor injection somehow. – Blake Rivell Jan 26 '16 at 14:37
  • @BlakeRivell: did you manage to get this going? I'm having the same issue – Ovi Mar 17 '16 at 15:16
  • @Ovi Post it as another question and link it here. I'll try to help you with it. – msmolcic Mar 17 '16 at 16:53
  • @msmolcic: Thanks! http://stackoverflow.com/questions/36071459/asp-net-5-mvc-6-configuration-in-class – Ovi Mar 17 '16 at 20:52
  • @Ovi The answer to this post will show you exactly how to do it: http://stackoverflow.com/questions/35015066/passing-applications-connection-string-down-to-a-repository-class-library-in-as – Blake Rivell Mar 18 '16 at 05:05