Configuration.GetSection gets value from appsetting.json but Configuration.GetSection.Bind always returns null

1.8k Views Asked by At

I have below code where I am trying to bind my appsettings.json with my variable and my variable is of class type whose model has been defined appropriately as per JSON schema.

During Debug, In quick watch I am able to see the value of my appsettings.json in config.GetSection("TableStorageRule") but for config.GetSection("TableStorageRule").Bind(tableStorageOutput) its null.

var builder = new ConfigurationBuilder()
        .SetBasePath(Path.Combine(Root))
        .AddJsonFile("appsettings.json", optional: false);

var config = builder.Build();

var tableStorageOutput = new TableStorageRule();            
config.GetSection("TableStorageRule").Bind(tableStorageOutput);
var nameOfFilter = tableStorageOutput.Name;

I would like to know what's wrong I am doing?

Here is my model class definition

public class TableStoreSettings
{
    public class AzureTableSettings
    {
        public string Account { get; set; }
        public string Key { get; set; }
        public string Table { get; set; }
    }

    public AzureTableSettings AzureTable { get; set; }

    public Uri SchemaBaseUri { get; set; }
}

public class TableStorageRule
{
    public string Name { get; set; }
    public TwisterDataFilter DataFilter { get; set; }
    public TableStoreSettings TableSettings { get; set; }
}

Here is my Json Schema>

{  "TableStorageRule": [
  {
    "Name": "filterRule1",
    "DataFilter": {
      "DataSetType": "Settings1"
    
    },
    "TableStoreSettings": {
      "AzureTable": {
        "Account": "account1",
        "Table": "table1",
        "Key": "key1"
      },
      "SchemaBaseUri": "https://test.web.core.windows.net/"
    }
  } 
]}
1

There are 1 best solutions below

2
Patrick Mcvay On BEST ANSWER

The problem is in your Json. TableStoreSettings needs to be renamed to TableSettings to match the class, and your TableStorageRule is not an array of rules.

{
  "TableStorageRule": {
    "Name": "filterRule1",
    "DataFilter": {
      "DataSetType": "Settings1"

    },
    "TableSettings": {
      "AzureTable": {
        "Account": "account1",
        "Table": "table1",
        "Key": "key1"
      },
      "SchemaBaseUri": "https://test.web.core.windows.net/"
    }
  }
  
}

If you are planning on having an array of rules, I would recommend putting another Top Level class.

    public class TableStorageRules
    {
        public List<TableStorageRule> Rules { get; set; }
    }

Then your Json would look like this

{
  "TableStorageRule": {
    "Rules": [
      
      {
        "Name": "filterRule1",
        "DataFilter":
        {
          "DataSetType": "Settings1"

        },
        "TableSettings":
        {
          "AzureTable": {
            "Account": "account1",
            "Table": "table1",
            "Key": "key1"
          },
          "SchemaBaseUri": "https://test.web.core.windows.net/"
        }

      }
    ]
  }

}

To Bind you would use this

        var builder = new ConfigurationBuilder()
                        .SetBasePath(Path.Combine(Root))
                        .AddJsonFile("appsettings.json", optional: false);

        var config = builder.Build();

        var tableStorageOutput = new TableStorageRules();
        config.GetSection("TableStorageRule").Bind(tableStorageOutput);
        var nameOfFilter = tableStorageOutput.Rules[0].Name;