you should inject the AuthenticationStateProvider instead of context.
Blazor Server IHttpContextAccessor returning null when deployed
I am dynamically setting the connection string based on the user that is logged in. This is working perfectly when running locally/debugging but when its deployed it's returning a null reference exception. This is my DbContext and I am handling the connection string logic in the OnConfigure method:
namespace SwordfishCRM.Services.ApplicationDbContext
{
public class PrimaryApplicationDbContext : IdentityDbContext<ApplicationUser>
{
private readonly HttpContext context;
private readonly IConfiguration configuration;
public PrimaryApplicationDbContext(DbContextOptions<PrimaryApplicationDbContext> options, IHttpContextAccessor httpContextAccessor, IConfiguration configuration) : base(options)
{
this.context = httpContextAccessor.HttpContext;
this.configuration = configuration;
}
//Tables
public DbSet<Address> Addresses { get; set; }
public DbSet<ChimneySweepCycle> ChimneySweepCycles { get; set; }
public DbSet<ChimneySweepMethod> ChimneySweepMethods { get; set; }
public DbSet<ContactMethod> ContactMethods { get; set; }
public DbSet<ContactPreference> ContactPreferences { get; set; }
public DbSet<Customer> Customers { get; set; }
public DbSet<Diary> Diary { get; set; }
public DbSet<DiaryDate> DiaryDates { get; set; }
public DbSet<DiaryOption> DiaryOptions { get; set; }
public DbSet<Gender> Genders { get; set; }
public DbSet<Job> Jobs { get; set; }
public DbSet<JobActualLine> JobActualLines { get; set; }
public DbSet<JobApproval> JobApprovals { get; set; }
public DbSet<JobQuoteLine> JobQuoteLines { get; set; }
public DbSet<JobStatus> JobStatuses { get; set; }
public DbSet<JobType> JobTypes { get; set; }
public DbSet<Product> Products { get; set; }
public DbSet<Report> Reports { get; set; }
public DbSet<RetroSweepingCertificate> RetroSweepingCertificates { get; set; }
public DbSet<ScheduleDay> ScheduleDays { get; set; }
public DbSet<ScheduleExceptionDay> ScheduleExceptionDays { get; set; }
public DbSet<Title> Titles { get; set; }
//Views
public virtual DbSet<vwAvailableApoointment> vwAvailableApoointments { get; set; }
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
modelBuilder
.Entity<vwAvailableApoointment>(eb =>
{
eb.HasNoKey();
eb.ToView("vwAvailableApoointments");
});
}
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
var userId = context.User.Identity.Name;
if (userId == null)
{
optionsBuilder.UseSqlServer(configuration.GetConnectionString("Master"));
}
else
{
var prefix = IdentitySupport.GetConnectionPrefix(userId);
optionsBuilder.UseSqlServer(configuration.GetConnectionString(prefix));
}
}
}
}
This is the console error when it's been deployed:
Error: System.NullReferenceException: Object reference not set to an instance of an object.
at SwordfishCRM.Services.ApplicationDbContext.PrimaryApplicationDbContext.OnConfiguring(DbContextOptionsBuilder optionsBuilder) in D:\a\1\s\SwordfishCRM.Services\ApplicationDbContext\PrimaryApplicationDbContext .cs:line 67
at Microsoft.EntityFrameworkCore.DbContext.get_ContextServices()
at Microsoft.EntityFrameworkCore.DbContext.get_Model()
at Microsoft.EntityFrameworkCore.Internal.InternalDbSet`1.get_EntityType()
at Microsoft.EntityFrameworkCore.Internal.InternalDbSet`1.CheckState()
at Microsoft.EntityFrameworkCore.Internal.InternalDbSet`1.get_EntityQueryable()
at Microsoft.EntityFrameworkCore.Internal.InternalDbSet`1.System.Linq.IQueryable.get_Provider()
at System.Linq.Queryable.OrderBy[TSource,TKey](IQueryable`1 source, Expression`1 keySelector)
at SwordfishCRM.Web.Pages.Swordfish.DiaryScheduleExceptionDates.OnInitializedAsync() in D:\a\1\s\SwordfishCRM.Web\Pages\Swordfish\DiaryScheduleExceptionDates.razor:line 25
at Microsoft.AspNetCore.Components.ComponentBase.RunInitAndSetParametersAsync()
I am confused why this run's locally but not when deployed. I would welcome any support. Thank you
I have tried different variations of HTTPContext but to no avail. I am expecting it to find the logged in user, so I can retrieve a code to set the connection string. There is a fail safe to use the config for the Master database (this is not the actual Master database, just a name for the main database with all the users etc...) There is a step before this that if they are not logged in, they wont even hit this screen.
Developer technologies .NET Entity Framework Core
Developer technologies .NET Blazor
-
Bruce (SqlWork.com) 77,686 Reputation points Volunteer Moderator
2023-01-09T20:48:36.343+00:00