Blazor Server IHttpContextAccessor returning null when deployed

Richard Baker 21 Reputation points
2023-01-09T17:22:52.197+00:00

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

Locked Question. You can vote on whether it's helpful, but you can't add comments or replies or follow the question.

Answer accepted by question author
Bruce (SqlWork.com) 85,111 Reputation points
2023-01-09T20:48:36.343+00:00

you should inject the AuthenticationStateProvider instead of context.

Was this answer helpful?

0 additional answers

Sort by: Most helpful