Question How access the connection string declared in appsettings.json in Blazor

Pablo

Well-known member
Joined
Aug 12, 2021
Messages
62
Programming Experience
10+
Hi,
So I was able to add a connection string to the file appsettings.json, but I can't find the way to retrieve it in my 'Service' C# code file which gets data from the DB.
What I could know is that I need an IConfiguration object, through whose GetConnectionString() method I would get the connection string, but ... from where do I get the IConfiguration object? Should I create one? Should I get it from certain place?
I have a 'Service' C# code file which gets data from the DB, like below:
CountryService.cs:
public class CountryService
{  
    public List<Country> GetCountries()
    {
        SqlConnection conn = new SqlConnection(configuration.GetConnectionString("myConnection"));
        ...
        ...
    }
}
Thank you.
Pablo
 
The same way you would with any .NET Core app: get the configuration object during startup and/or, or through dependency injection and the inverse of control framework.

Below is one way to get the confiyonject during startup:
 
I don't put CSs in appsettings.json, by the way - CSs typically contain sensitive info and should instead be put in user secrets, env vars etc - something that doesn't end up in source control. If you deploy your app to something like Azure, then you use their management portal to house your settings, which is again more secure than in a file that your site could potentially be tricked into serving up to the world

You can get visual studio and to help you with all this. We also don't gerneally bother writing such low level SQL for basic things like "get a list of countries"

I made a project, I added a connected service of "on prem SQLS", conn str stored in user secrets, did the wizard to design the connection string:

1689626466145.png



1689626450444.png



It's in user secrets now:

1689626513299.png


1689626545503.png




Separately I actually connect to the database and form an EF context for it:


1689626610133.png


EFCPT is an extension that takes a lot of the pain of DB related work away

I choose the tables I want to work with. and options like wher eto put classes generated from them:

1689626685216.png


I'm nearly ready to go, I just need to register to use this ScratchContext (DB name is "Scratch")

In Blazor server we don't inject contexts, because they become too long lived for boring technical reasons I won't cover. Instead we inject context factories and manufacture contexts when we want one


For this to work we have to tell the IoC what to inject, and we do this in program.cs:

C#:
builder.Services.AddDbContextFactory<ScratchContext>(optionsBuilder =>
{
    var cs = builder.Configuration.GetConnectionString("ConnectionStrings:Local");
    optionsBuilder.UseSqlServer(connectionString: cs); //if you used MySQL etc this line would look different
});

Then in some Blazor page, or service, whatever, we inject that thing:

C#:
//in some page that has a separate codebehind
class SomePage:ComponentBase
{
    [Inject]
    IDbContextFactory<ScratchContext> contextFactory;

}


//in some page that has no codebehind
@inject IDbContextFactory<ScratchContext> ContextFactory


//in some normal class constructor that is a service or whatever
class MyService
{

  IDbContextFactory<ScratchContext> _contextFactory;

  public MyService(IDbContextFactory<ScratchContext> contextFactory)
  {
    _contextFactory = contextFactory;
  }

When we want to run a query:


C#:
  async Task GetAllCountriesClick()
  {

    var context = _contextFactory.CreateContext();
    var countriesList = context.Countries.Where(c => c.Language == "ENglish").OrderBy("c => c.TimeZoneOffset).ToListAsync();

  }


----

If you really want to carry on with ADO and passing connectionstrings, just inject an IConfiguration and call .GetConnectionString("Your_Conn_Str_Name_In_User_Secrets_Here");. Microsoft DI already knows how to provide IConfiguration; you don't need to register it

If youre not using DI, eg if youre using a console app, you might want to build your configurator and tell it all the places to search to get config; later items overwrite earlier items so...


C#:
            _config = new ConfigurationBuilder()
                .SetBasePath(AppDomain.CurrentDomain.BaseDirectory)
                .AddJsonFile("appsettings.json")
                .AddUserSecrets<Program>()
                .AddANythingElseYouWantToGetConfigFromLikeEnvVarsEtc()
                .Build();

Here items in User Secrets displace items in app settings etc..

And again call it like before _config.GetConnectionString("...")
 
Hello, Skydiver
Thank you for your reply, though I can't understand much without an example code, and as I know the Startup file/class remained in the past, it doesn't exist any more. Thank you, anyway.
Hello cjard
I appreciate your help very much, I am currently following your instructions; I'll continue with ADO up to finish this project, then I'll try to do the same with EF as you suggest.
Regards
Pablo
 
I don't think you'll look back; I have only very rarely dropped back to using TableAdapters, which are a step up from raw ADO.net, since getting the tooling together to make EF life easy
 
hi Pablo, gosh it's so good to see a someone with problems i can relate too, i had similiar problemas and i am currently using ado.net instead of EF, so here's what you want to do: after adding the CS in the appsetting you need to register it as a service into the dependency injection container inside program.cs. i don't know which provider you are using but the thing goes like this:
the code:
Builder.Services.AddScoped<SqlConnection>(

e => new SqlConnection(builder.Configuration.GetConnectionString("myConnection"))
)
 
hi Pablo, gosh it's so good to see a someone with problems i can relate too, i had similiar problemas and i am currently using ado.net instead of EF, so here's what you want to do: after adding the CS in the appsetting you need to register it as a service into the dependency injection container inside program.cs. i don't know which provider you are using but the thing goes like this:
the code:
Builder.Services.AddScoped<SqlConnection>(

e => new SqlConnection(builder.Configuration.GetConnectionString("myConnection"))
)

and then you can use with deppendency injection in your controller
 
I'd perhaps caution against doing this in a Blazor Server application; the connection lives for the lifetime of the circuit the user is connected to so a) you can only have one connection per user and b) you can potentially have one connection per user (don't forget to close it)
 

Latest posts

Back
Top Bottom