Search code examples
c#asp.net-coreasp.net-core-configuration

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


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/"
    }
  } 
]}

Solution

  • 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;