I am using Azure .NET core WebApp, MVC, Entity Framework, scaffolded in an existing external MS SQL database.
I register the DB in the startup ConfigureServices like this:
services.AddDbContext<MyDbContext>(options => options.UseSqlServer());
And it works fine so long as I set the connection string in the MyDbContext.cs OnConfiguring() method like this:
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
optionsBuilder.UseSqlServer("Server=10.10.10.10;Database=MyDb;user id=username;password=password;");
}
Then I can simply in a Controller say:
private readonly MyDbContext _context;
public HomeController()
{
_context = new MyDbContext();
}
public IActionResult Index()
{
var item = _context.TableName.FirstOrDefault(d => d.Id > 0);
}
And this works fine - data flows in.
My problem is that I need to change the SQL connection string depending on what hostname is connecting. So, either in the startup ConfigureServices() I can pass the connection if I can establish the hostname being used, or in the DB's MyDbContext.cs file's OnConfiguring() method.
I can get the hostname only from the httpcontext, and that isn't available to query in the startup so far as I can tell?
If I try and inject it into the context.cs DB file, like this:
public partial class MyDbContext : DbContext
{
private readonly IHttpContextAccessor _httpContextAccessor;
public MyDbContext()
{
}
public MyDbContext(IHttpContextAccessor httpContextAccessor)
{
_httpContextAccessor = httpContextAccessor; // For context/url
}
public MyDbContext(DbContextOptions<MyDbContext> options, IHttpContextAccessor httpContextAccessor)
: base(options)
{
_httpContextAccessor = httpContextAccessor; // For context/url
}
Then the startup ConfigureServices line services.AddDbContext can't pass the httpcontext (it doesn't exist at that point?) none of the constructor methods match - I can't inject the IHttpContextAccessor httpContextAccessor into the DB context method no matter how I try!
services.AddDbContext<MyDbContext>(options => options.UseSqlServer("some-connection-string")); // Doesn't pass httpcontext
services.AddDbContext<MyDbContext>()); // Doesn't pass httpcontext
services.AddDbContext<MyDbContext>(is there way to pass it?);
It doesn't seem to work like injecting it into Controllers, which does work fine as there's no constructor there...
Any ideas on how I can find the hostname and change the SQL connection string given this setup?
For various reasons this needs to be a single WebApp that multiple domains use by the way.
edit
After a sleepless night I woke up and decided to simply connect to all (three) databases I need and then decide which context to use in the controller, as I have the httpcontext there to decide what host is connecting. It's not ideal, but this is a low overhead WebApp so I'm happy enough to go with it like that. I think perhaps there is/was a solution out there though...
IHttpContextAccessorinto yourDbContext, you get an exception on theservices.AddDbContextline? It sure feels like that should be the way to go. - Jesse de Wit