Search code examples
c#asp.net-core-mvcconnection-stringdapper

ConnectionString not initialized .net core


I reproduced a way to access the database with .net Framework but it doesn't work in .net Core. I found a way to fix it and followed what was said but I get the error that the connectionString is not initialized. Therefore, I don't know how to get it working.

Code I'm using:

public class DataAccess
{
    private string _connectionString;

    public DataAccess(string connectionString)
    {
        _connectionString = connectionString;
    }

    public List<PropertyModel> LoadData()
    {
        var data = new List<PropertyModel>();

        using(IDbConnection cnn = new SqlConnection(_connectionString))
        {
            data = cnn.Query<PropertyModel>(@"select *
                        from dbo.PropertyModel;").ToList();
        }
        return data;
    }
}

In Controller:

private DataAccess data;

    public PropertyController(IOptions<ConnectionConfig> connectionConfig)
    {
        var connection = connectionConfig.Value;
        string connectionString = connection.Analysis;
        data = new DataAccess(connectionString);
    }

    public IActionResult Index()
    {
        var test = data.LoadData();
        return View();
    }

In StartUp:

 services.Configure<ConnectionConfig
(Configuration.GetSection("MVCCoreAppDB"));

And I created a POCO class:

public class ConnectionConfig
{
    public string Analysis { get; set; }
}

I followed this.

appsettings.json:

"ConnectionStrings": {
"MVCCoreAppDB": "Data Source=(localdb)\\MSSQLLocalDB;Initial Catalog=MVCCoreAppDB;Integrated Security=True;Connect Timeout=60;Encrypt=False;TrustServerCertificate=False;ApplicationIntent=ReadWrite;MultiSubnetFailover=False"},

Solution

  • You are calling the wrong section from configuration.

    services.Configure<ConnectionConfig>(Configuration.GetSection("ConnectionStrings"));
    

    You would also need to update the model

    public class ConnectionConfig {
        public string MVCCoreAppDB { get; set; }
    }
    

    That said I would suggest you change your design to populate the model upfront and register it with the service collection for injection

    In StartUp:

    services.AddScoped<DataAccess>(_ => 
        new DataAccess(Configuration.GetConnectionString("MVCCoreAppDB"))
    );
    

    And inject the data access explicitly into the controller

    private readonly DataAccess data;
    
    public PropertyController(DataAccess data) {
        this.data = data;
    }
    
    public IActionResult Index() {
        var test = data.LoadData();
        return View();
    }
    

    Reference Explicit Dependencies Principle